diff --git a/.cargo/config.toml b/.cargo/config.toml index 4d80d3ce63da..48a63e485681 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,5 +1,7 @@ [alias] uitest = "test --test compile-test" +uibless = "test --test compile-test -- -- --bless" +bless = "test -- -- --bless" dev = "run --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --" lintcheck = "run --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml -- " collect-metadata = "test --test dogfood --features internal -- run_metadata_collection_lint --ignored" diff --git a/.github/ISSUE_TEMPLATE/new_lint.yml b/.github/ISSUE_TEMPLATE/new_lint.yml index 0b43d8d70c00..b49493edce1b 100644 --- a/.github/ISSUE_TEMPLATE/new_lint.yml +++ b/.github/ISSUE_TEMPLATE/new_lint.yml @@ -12,29 +12,6 @@ body: description: What does this lint do? validations: required: true - - type: input - id: lint-name - attributes: - label: Lint Name - description: Please provide the lint name. - - type: dropdown - id: category - attributes: - label: Category - description: > - What category should this lint go into? If you're unsure you can select - multiple categories. You can find a category description in the - `README`. - multiple: true - options: - - correctness - - suspicious - - style - - complexity - - perf - - pedantic - - restriction - - cargo - type: textarea id: advantage attributes: diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index b99213011971..410ff53a251b 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -25,7 +25,6 @@ env: CARGO_TARGET_DIR: '${{ github.workspace }}/target' NO_FMT_TEST: 1 CARGO_INCREMENTAL: 0 - CARGO_UNSTABLE_SPARSE_REGISTRY: true jobs: base: @@ -39,7 +38,7 @@ jobs: github_token: "${{ secrets.github_token }}" - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3 - name: Install toolchain run: rustup show active-toolchain @@ -51,7 +50,7 @@ jobs: echo "LD_LIBRARY_PATH=${SYSROOT}/lib${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV - name: Build - run: cargo build --features deny-warnings,internal + run: cargo build --tests --features deny-warnings,internal - name: Test run: cargo test --features deny-warnings,internal diff --git a/.github/workflows/clippy_bors.yml b/.github/workflows/clippy_bors.yml index 93198aabdb5f..4eb11a3ac857 100644 --- a/.github/workflows/clippy_bors.yml +++ b/.github/workflows/clippy_bors.yml @@ -11,7 +11,6 @@ env: CARGO_TARGET_DIR: '${{ github.workspace }}/target' NO_FMT_TEST: 1 CARGO_INCREMENTAL: 0 - CARGO_UNSTABLE_SPARSE_REGISTRY: true defaults: run: @@ -27,7 +26,7 @@ jobs: github_token: "${{ secrets.github_token }}" - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3 with: ref: ${{ github.ref }} @@ -83,7 +82,7 @@ jobs: github_token: "${{ secrets.github_token }}" - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3 - name: Install toolchain run: rustup show active-toolchain @@ -107,7 +106,7 @@ jobs: echo "$SYSROOT/bin" >> $GITHUB_PATH - name: Build - run: cargo build --features deny-warnings,internal + run: cargo build --tests --features deny-warnings,internal - name: Test if: runner.os == 'Linux' @@ -149,7 +148,7 @@ jobs: github_token: "${{ secrets.github_token }}" - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3 - name: Install toolchain run: rustup show active-toolchain @@ -173,7 +172,7 @@ jobs: github_token: "${{ secrets.github_token }}" - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3 - name: Install toolchain run: rustup show active-toolchain @@ -233,7 +232,7 @@ jobs: github_token: "${{ secrets.github_token }}" - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3 - name: Install toolchain run: rustup show active-toolchain diff --git a/.github/workflows/clippy_dev.yml b/.github/workflows/clippy_dev.yml index 14f20212adda..0f0e3f2db925 100644 --- a/.github/workflows/clippy_dev.yml +++ b/.github/workflows/clippy_dev.yml @@ -16,7 +16,6 @@ on: env: RUST_BACKTRACE: 1 CARGO_INCREMENTAL: 0 - CARGO_UNSTABLE_SPARSE_REGISTRY: true jobs: clippy_dev: @@ -25,7 +24,7 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3 # Run - name: Build diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 71d71d10359e..f42928c2cd11 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -21,10 +21,10 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3 - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3 with: ref: ${{ env.TARGET_BRANCH }} path: 'out' diff --git a/.github/workflows/remark.yml b/.github/workflows/remark.yml index 116058b7c753..7d25b6a2b79e 100644 --- a/.github/workflows/remark.yml +++ b/.github/workflows/remark.yml @@ -16,10 +16,10 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3 - name: Setup Node.js - uses: actions/setup-node@v1.4.4 + uses: actions/setup-node@v3 with: node-version: '14.x' @@ -36,6 +36,12 @@ jobs: - name: Check *.md files run: git ls-files -z '*.md' | xargs -0 -n 1 -I {} ./node_modules/.bin/remark {} -u lint -f > /dev/null + - name: Linkcheck book + run: | + rustup toolchain install nightly --component rust-docs + curl https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh -o linkcheck.sh + sh linkcheck.sh clippy --path ./book + - name: Build mdbook run: mdbook build book diff --git a/CHANGELOG.md b/CHANGELOG.md index b868f1db606c..8c3496eaa287 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,13 +6,474 @@ document. ## Unreleased / Beta / In Rust Nightly -[7f27e2e7...master](https://github.com/rust-lang/rust-clippy/compare/7f27e2e7...master) +<<<<<<< HEAD +[435a8ad8...master](https://github.com/rust-lang/rust-clippy/compare/435a8ad8...master) + +## Rust 1.71 + +Current stable, released 2023-07-13 + + + +We're trying out a new shorter changelog format, that only contains significant changes. +You can check out the list of merged pull requests for a list of all changes. +If you have any feedback related to the new format, please share it in +[#10847](https://github.com/rust-lang/rust-clippy/issues/10847) + +[View all 78 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-04-11T20%3A05%3A26Z..2023-05-20T13%3A48%3A17Z+base%3Amaster) + +### New Lints + +* [`non_minimal_cfg`] + [#10763](https://github.com/rust-lang/rust-clippy/pull/10763) +* [`manual_next_back`] + [#10769](https://github.com/rust-lang/rust-clippy/pull/10769) +* [`ref_patterns`] + [#10736](https://github.com/rust-lang/rust-clippy/pull/10736) +* [`default_constructed_unit_structs`] + [#10716](https://github.com/rust-lang/rust-clippy/pull/10716) +* [`manual_while_let_some`] + [#10647](https://github.com/rust-lang/rust-clippy/pull/10647) +* [`needless_bool_assign`] + [#10432](https://github.com/rust-lang/rust-clippy/pull/10432) +* [`items_after_test_module`] + [#10578](https://github.com/rust-lang/rust-clippy/pull/10578) + +### Moves and Deprecations + +* Rename `integer_arithmetic` to `arithmetic_side_effects` + [#10674](https://github.com/rust-lang/rust-clippy/pull/10674) +* Moved [`redundant_clone`] to `nursery` (Now allow-by-default) + [#10873](https://github.com/rust-lang/rust-clippy/pull/10873) + +### Enhancements + +* [`invalid_regex`]: Now supports the new syntax introduced after regex v1.8.0 + [#10682](https://github.com/rust-lang/rust-clippy/pull/10682) +* [`semicolon_outside_block`]: Added [`semicolon-outside-block-ignore-multiline`] as a new config value. + [#10656](https://github.com/rust-lang/rust-clippy/pull/10656) +* [`semicolon_inside_block`]: Added [`semicolon-inside-block-ignore-singleline`] as a new config value. + [#10656](https://github.com/rust-lang/rust-clippy/pull/10656) +* [`unnecessary_box_returns`]: Added [`unnecessary-box-size`] as a new config value to set the maximum + size of `T` in `Box` to be linted. + [#10651](https://github.com/rust-lang/rust-clippy/pull/10651) + +### Documentation Improvements + +* `cargo clippy --explain LINT` now shows possible configuration options for the explained lint + [#10751](https://github.com/rust-lang/rust-clippy/pull/10751) +* New config values mentioned in this changelog will now be linked. + [#10889](https://github.com/rust-lang/rust-clippy/pull/10889) +* Several sections of [Clippy's book] have been reworked + [#10652](https://github.com/rust-lang/rust-clippy/pull/10652) + [#10622](https://github.com/rust-lang/rust-clippy/pull/10622) + +[Clippy's book]: https://doc.rust-lang.org/clippy/ + +## Rust 1.70 + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +Current stable, released 2023-06-01 +======= +Released 2023-06-01 +>>>>>>> 7a3756add (Changelog: Add disclaimer about the new format) + +<<<<<<< HEAD +[**View 85 PRs merged since 1.69**](https://github.com/rust-lang/rust-clippy/pulls?q=is%3Apr+is%3Aclosed+merged%3A2023-04-20..2023-06-01+base%3Amaster+sort%3Amerged-desc+) +<<<<<<< HEAD +======= +Current beta, released 2023-06-01 +======= +Current stable, released 2023-06-01 +>>>>>>> a28eb5995 (Update *Current stable* text in `CHANGELOG.md`) + +[149392b0...83e42a23](https://github.com/rust-lang/rust-clippy/compare/149392b0...83e42a23) +>>>>>>> 4d9303df1 (Changelog for Rust 1.70 :hammer:) +======= +>>>>>>> aea731ebd (update changelog's data ranges) +======= +[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-02-26T01%3A05%3A43Z..2023-04-11T13%3A27%3A30Z+base%3Amaster) +>>>>>>> 28655266b (Fix changelog PR listings, create them automatically in `fetch_prs_between.sh`) + +### New Lints + +* [`large_futures`] + [#10414](https://github.com/rust-lang/rust-clippy/pull/10414) +* [`missing_assert_message`] + [#10362](https://github.com/rust-lang/rust-clippy/pull/10362) +* [`clear_with_drain`] + [#10528](https://github.com/rust-lang/rust-clippy/pull/10528) +* [`redundant_async_block`] + [#10448](https://github.com/rust-lang/rust-clippy/pull/10448) +* [`collection_is_never_read`] + [#10415](https://github.com/rust-lang/rust-clippy/pull/10415) +* [`let_with_type_underscore`] + [#10467](https://github.com/rust-lang/rust-clippy/pull/10467) +* [`tests_outside_test_module`] + [#10543](https://github.com/rust-lang/rust-clippy/pull/10543) +* [`allow_attributes`] + [#10481](https://github.com/rust-lang/rust-clippy/pull/10481) +* [`suspicious_doc_comments`] + [#10497](https://github.com/rust-lang/rust-clippy/pull/10497) +* [`unnecessary_box_returns`] + [#9102](https://github.com/rust-lang/rust-clippy/pull/9102) +* [`manual_main_separator_str`] + [#10483](https://github.com/rust-lang/rust-clippy/pull/10483) +* [`unnecessary_struct_initialization`] + [#10489](https://github.com/rust-lang/rust-clippy/pull/10489) +* [`manual_slice_size_calculation`] + [#10601](https://github.com/rust-lang/rust-clippy/pull/10601) +* [`lines_filter_map_ok`] + [#10534](https://github.com/rust-lang/rust-clippy/pull/10534) + +### Moves and Deprecations + +* Moved [`let_underscore_untyped`] to `restriction` + [#10442](https://github.com/rust-lang/rust-clippy/pull/10442) + +### Enhancements + +* [`extra_unused_type_parameters`]: No longer lints on public items if `avoid-breaking-exported-api` is set + [#10536](https://github.com/rust-lang/rust-clippy/pull/10536) +* [`len_without_is_empty`]: Now also detects `async` functions + [#10359](https://github.com/rust-lang/rust-clippy/pull/10359) +* [`arithmetic_side_effects`]: Now correctly handles divisions and modulo expressions if the right-hand-side + is unknown + [#10585](https://github.com/rust-lang/rust-clippy/pull/10585) +* [`nonminimal_bool`]: No longer ignores `#[allow]` attributes + [#10588](https://github.com/rust-lang/rust-clippy/pull/10588) +* [`uninit_vec`], [`uninit_assumed_init`]: Now uses a better heuristic + [#10520](https://github.com/rust-lang/rust-clippy/pull/10520) +* [`ifs_same_cond`]: Now also detects immutable method calls. + [#10350](https://github.com/rust-lang/rust-clippy/pull/10350) +* [`arithmetic_side_effects`]: No longer lints on right or left shifts with constant integers, as the + compiler warns about them + [#10309](https://github.com/rust-lang/rust-clippy/pull/10309) +* [`items_after_statements`]: `#[allow(items_after_statements)]` now works on items + [#10542](https://github.com/rust-lang/rust-clippy/pull/10542) +<<<<<<< HEAD +<<<<<<< HEAD +* [`significant_drop_tightening`]: Was optimized +======= +* [`significant_drop_tightening`]: was optimized +>>>>>>> 4d9303df1 (Changelog for Rust 1.70 :hammer:) +======= +* [`significant_drop_tightening`]: Was optimized +>>>>>>> 7dd0ae026 (Change changelog typos) + [#10533](https://github.com/rust-lang/rust-clippy/pull/10533) + +### False Positive Fixes + +* [`single_component_path_imports`]: No longer lints if the import is used relative to `self` + [#10566](https://github.com/rust-lang/rust-clippy/pull/10566) +* [`derivable_impls`]: No longer suggests deriving `Default` on generics with implicit arguments + [#10399](https://github.com/rust-lang/rust-clippy/pull/10399) +* [`let_unit_value`]: No longer lints if the expression contains an `await` + [#10439](https://github.com/rust-lang/rust-clippy/pull/10439) +* [`double_must_use`]: Now ignores `async` functions + [#10589](https://github.com/rust-lang/rust-clippy/pull/10589) +* [`manual_clamp`]: No longer lints in constant context + [#10479](https://github.com/rust-lang/rust-clippy/pull/10479) +* [`almost_swapped`]: Now ignores external macros + [#10502](https://github.com/rust-lang/rust-clippy/pull/10502) +* [`nonminimal_bool`]: Now ignores macros + [#10527](https://github.com/rust-lang/rust-clippy/pull/10527) +* [`needless_return`]: No longer lints match statements with incompatible branches + [#10593](https://github.com/rust-lang/rust-clippy/pull/10593) +<<<<<<< HEAD +<<<<<<< HEAD +* [`use_self`]: Do not suggest using `Self` in const generic parameters + [#10375](https://github.com/rust-lang/rust-clippy/pull/10375) +* [`mem_replace_option_with_none`]: No longer lints on field expressions + [#10594](https://github.com/rust-lang/rust-clippy/pull/10594) +* [`items_after_statements`]: No longer lints on items from macros +<<<<<<< HEAD +======= +* [`use_self`]: do not suggest using `Self` in const generic parameters +======= +* [`use_self`]: Do not suggest using `Self` in const generic parameters +>>>>>>> 7dd0ae026 (Change changelog typos) + [#10375](https://github.com/rust-lang/rust-clippy/pull/10375) +* [`mem_replace_option_with_none`]: No longer lints on field expressions + [#10594](https://github.com/rust-lang/rust-clippy/pull/10594) +* [`items_after_statements`]: No longer lints on times from macros +>>>>>>> 4d9303df1 (Changelog for Rust 1.70 :hammer:) +======= +>>>>>>> a28eb5995 (Update *Current stable* text in `CHANGELOG.md`) + [#10542](https://github.com/rust-lang/rust-clippy/pull/10542) +* [`print_literal`], [`write_literal`]: No longer lint strings coming from the `file!()` macro + [#10573](https://github.com/rust-lang/rust-clippy/pull/10573) +* [`uninit_vec`], [`uninit_assumed_init`]: Now check the types inside arrays and tuples + [#10553](https://github.com/rust-lang/rust-clippy/pull/10553) +* [`almost_swapped`]: No longer lints if a variable is assigned to itself + [#10499](https://github.com/rust-lang/rust-clippy/pull/10499) +* [`missing_docs_in_private_items`]: No longer lints on public items + [#10324](https://github.com/rust-lang/rust-clippy/pull/10324) + +### Suggestion Fixes/Improvements + +* [`extra_unused_type_parameters`]: The suggestion is now machine applicable + [#10536](https://github.com/rust-lang/rust-clippy/pull/10536) +* [`match_single_binding`]: Now adds a semicolon after the suggestion + [#10470](https://github.com/rust-lang/rust-clippy/pull/10470) +* [`missing_const_for_fn`]: Now includes a note if the change could break compatibility + [#10618](https://github.com/rust-lang/rust-clippy/pull/10618) +* [`cast_possible_truncation`]: Corrected suggestion for float and wildcard casts + [#10496](https://github.com/rust-lang/rust-clippy/pull/10496) +* [`transmutes_expressible_as_ptr_casts`]: The suggestion now includes parentheses when they are required + [#10454](https://github.com/rust-lang/rust-clippy/pull/10454) + +### ICE Fixes + +* [`needless_borrow`]: No longer panics on ambiguous projections + [#10403](https://github.com/rust-lang/rust-clippy/pull/10403) +* [`multiple_unsafe_ops_per_block`]: Fix ICE when calling a function-like object in an unsafe block + [#10405](https://github.com/rust-lang/rust-clippy/pull/10405) + +### Others + +* `clippy-driver` now searches parent directories for `clippy.toml` files + [#10592](https://github.com/rust-lang/rust-clippy/pull/10592) +* Fixed a deserialization error for the `array-size-threshold` config value + [#10423](https://github.com/rust-lang/rust-clippy/pull/10423) + +## Rust 1.69 + +Released 2023-04-20 + +[View all 72 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-01-13T06%3A12%3A46Z..2023-02-25T23%3A48%3A10Z+base%3Amaster) +======= +[149392b0...master](https://github.com/rust-lang/rust-clippy/compare/149392b0...master) + +## Rust 1.69 + +Current stable, released 2023-04-20 + +[7f27e2e7...149392b0](https://github.com/rust-lang/rust-clippy/compare/7f27e2e7...149392b0) +>>>>>>> e4f5d83fa (Fixed formatting.) + +### New Lints + +* [`no_mangle_with_rust_abi`] + [#10369](https://github.com/rust-lang/rust-clippy/pull/10369) +* [`significant_drop_tightening`] + [#10163](https://github.com/rust-lang/rust-clippy/pull/10163) +* [`suspicious_command_arg_space`] + [#10317](https://github.com/rust-lang/rust-clippy/pull/10317) +* [`let_underscore_untyped`] + [#10356](https://github.com/rust-lang/rust-clippy/pull/10356) +* [`question_mark_used`] + [#10342](https://github.com/rust-lang/rust-clippy/pull/10342) +* [`extra_unused_type_parameters`] + [#10028](https://github.com/rust-lang/rust-clippy/pull/10028) +* [`impl_trait_in_params`] + [10197](https://github.com/rust-lang/rust-clippy/pull/10197) +* [`transmute_int_to_non_zero`] + [#10360](https://github.com/rust-lang/rust-clippy/pull/10360) +* [`multiple_unsafe_ops_per_block`] + [#10206](https://github.com/rust-lang/rust-clippy/pull/10206) + +### Moves and Deprecations + +* Moved [`uninlined_format_args`] to `pedantic` (Now allow-by-default) + [#10265](https://github.com/rust-lang/rust-clippy/pull/10265) +* Moved [`unchecked_duration_subtraction`] to `pedantic` (Now allow-by-default) + [#10194](https://github.com/rust-lang/rust-clippy/pull/10194) + +### Enhancements + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +* [`arithmetic_side_effects`]: No longer lints if safe constant values are used. +======= +* [`arithmetic_side_effects`]: No longer lints, if safe constant values are used. +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +* [`arithmetic_side_effects`]: No longer lints, if safe constant values are used. +>>>>>>> 6ce346c94 (Changelog for Rust 1.69 :cherry_blossom:) +======= +* [`arithmetic_side_effects`]: No longer lints if safe constant values are used. +>>>>>>> 637d10b29 (Catching, stray, commas, (I'll, never, learn, to, use, them, correctly) :sweat_smile:) + [#10310](https://github.com/rust-lang/rust-clippy/pull/10310) +* [`needless_lifetimes`]: Now works in local macros + [#10257](https://github.com/rust-lang/rust-clippy/pull/10257) +* [`unused_io_amount`]: Now detects usages of `is_ok` and `is_err` + [#10225](https://github.com/rust-lang/rust-clippy/pull/10225) +* [`missing_docs_in_private_items`]: Added new configuration `missing-docs-in-crate-items` to lint + on items visible within the current crate. For example, `pub(crate)` items. + [#10303](https://github.com/rust-lang/rust-clippy/pull/10303) +* [`almost_swapped`]: Now detects almost swaps using `let` statements + [#10177](https://github.com/rust-lang/rust-clippy/pull/10177) +* [`wildcard_enum_match_arm`]: Now lints missing private variants, for local enums + [#10250](https://github.com/rust-lang/rust-clippy/pull/10250) + +### False Positive Fixes + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +* [`explicit_auto_deref`]: Now considers projections when determining if auto deref is applicable + [#10386](https://github.com/rust-lang/rust-clippy/pull/10386) +<<<<<<< HEAD +* [`manual_let_else`]: Now considers side effects of branches before linting +======= +<<<<<<< HEAD +* [`manual_let_else`]: Now considers side effects of branches before linting +======= +* [`manual_let_else`]: Now considers side effects of branches before linting +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + [#10336](https://github.com/rust-lang/rust-clippy/pull/10336) +* [`uninlined_format_args`]: No longer lints for arguments with generic parameters + [#10343](https://github.com/rust-lang/rust-clippy/pull/10343) +* [`needless_lifetimes`]: No longer lints signatures in macros if the lifetime is a metavariable + [#10380](https://github.com/rust-lang/rust-clippy/pull/10380) +* [`len_without_is_empty`]: No longer lints if `len` as a non-default signature + [#10255](https://github.com/rust-lang/rust-clippy/pull/10255) +* [`unusual_byte_groupings`]: Relaxed the required restrictions for specific sizes to reduce false +======= +======= +>>>>>>> 6ce346c94 (Changelog for Rust 1.69 :cherry_blossom:) +* [`explicit_auto_deref`]: Now considers projections, when determining if auto deref is applicable +======= +* [`explicit_auto_deref`]: Now considers projections when determining if auto deref is applicable +>>>>>>> 637d10b29 (Catching, stray, commas, (I'll, never, learn, to, use, them, correctly) :sweat_smile:) + [#10386](https://github.com/rust-lang/rust-clippy/pull/10386) +* [`manual_let_else`]: Now considers side effects of branches before linting + [#10336](https://github.com/rust-lang/rust-clippy/pull/10336) +* [`uninlined_format_args`]: No longer lints for arguments with generic parameters + [#10343](https://github.com/rust-lang/rust-clippy/pull/10343) +* [`needless_lifetimes`]: No longer lints signatures in macros if the lifetime is a metavariable + [#10380](https://github.com/rust-lang/rust-clippy/pull/10380) +* [`len_without_is_empty`]: No longer lints if `len` as a non-default signature + [#10255](https://github.com/rust-lang/rust-clippy/pull/10255) +<<<<<<< HEAD +* [`unusual_byte_groupings`]: Relaxed the required restrictions for specific sizes, to reduce false +<<<<<<< HEAD +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 6ce346c94 (Changelog for Rust 1.69 :cherry_blossom:) +======= +* [`unusual_byte_groupings`]: Relaxed the required restrictions for specific sizes to reduce false +>>>>>>> 637d10b29 (Catching, stray, commas, (I'll, never, learn, to, use, them, correctly) :sweat_smile:) + positives + [#10353](https://github.com/rust-lang/rust-clippy/pull/10353) +* [`manual_let_else`]: No longer lints `if-else` blocks if they can divergent + [#10332](https://github.com/rust-lang/rust-clippy/pull/10332) +* [`expect_used`], [`unwrap_used`], [`dbg_macro`], [`print_stdout`], [`print_stderr`]: No longer lint +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + in test functions if `allow-expect-in-tests` is set + [#10391](https://github.com/rust-lang/rust-clippy/pull/10391) +* [`unnecessary_safety_comment`]: No longer lints code inside macros + [#10106](https://github.com/rust-lang/rust-clippy/pull/10106) +* [`never_loop`]: No longer lints statements following break statements for outer blocks. +======= +======= +>>>>>>> 6ce346c94 (Changelog for Rust 1.69 :cherry_blossom:) + in test functions, if `allow-expect-in-tests` is set + [#10391](https://github.com/rust-lang/rust-clippy/pull/10391) +* [`unnecessary_safety_comment`]: No longer lints code inside macros + [#10106](https://github.com/rust-lang/rust-clippy/pull/10106) +* [`never_loop`]: No longer lints, for statements following break statements for outer blocks. +<<<<<<< HEAD +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 6ce346c94 (Changelog for Rust 1.69 :cherry_blossom:) +======= + in test functions if `allow-expect-in-tests` is set + [#10391](https://github.com/rust-lang/rust-clippy/pull/10391) +* [`unnecessary_safety_comment`]: No longer lints code inside macros + [#10106](https://github.com/rust-lang/rust-clippy/pull/10106) +* [`never_loop`]: No longer lints statements following break statements for outer blocks. +>>>>>>> 637d10b29 (Catching, stray, commas, (I'll, never, learn, to, use, them, correctly) :sweat_smile:) + [#10311](https://github.com/rust-lang/rust-clippy/pull/10311) + +### Suggestion Fixes/Improvements + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +* [`box_default`]: The suggestion now includes the type for trait objects when needed +======= +* [`box_default`]: The suggestion now includes the type for trait objects, when needed +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +* [`box_default`]: The suggestion now includes the type for trait objects, when needed +>>>>>>> 6ce346c94 (Changelog for Rust 1.69 :cherry_blossom:) +======= +* [`box_default`]: The suggestion now includes the type for trait objects when needed +>>>>>>> 637d10b29 (Catching, stray, commas, (I'll, never, learn, to, use, them, correctly) :sweat_smile:) + [#10382](https://github.com/rust-lang/rust-clippy/pull/10382) +* [`cast_possible_truncation`]: Now suggests using `try_from` or allowing the lint + [#10038](https://github.com/rust-lang/rust-clippy/pull/10038) +* [`invalid_regex`]: Regex errors for non-literals or regular strings containing escape sequences will + now show the complete error + [#10231](https://github.com/rust-lang/rust-clippy/pull/10231) +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +* [`transmutes_expressible_as_ptr_casts`]: The suggestion now works if the base type is borrowed +======= +* [`transmutes_expressible_as_ptr_casts`]: The suggestion now works, if the base type is borrowed +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +* [`transmutes_expressible_as_ptr_casts`]: The suggestion now works, if the base type is borrowed +>>>>>>> 6ce346c94 (Changelog for Rust 1.69 :cherry_blossom:) +======= +* [`transmutes_expressible_as_ptr_casts`]: The suggestion now works if the base type is borrowed +>>>>>>> 637d10b29 (Catching, stray, commas, (I'll, never, learn, to, use, them, correctly) :sweat_smile:) + [#10193](https://github.com/rust-lang/rust-clippy/pull/10193) +* [`needless_return`]: Now removes all semicolons on the same line + [#10187](https://github.com/rust-lang/rust-clippy/pull/10187) +* [`suspicious_to_owned`]: The suggestion now shows all options clearly + [#10295](https://github.com/rust-lang/rust-clippy/pull/10295) +* [`bytes_nth`]: Now suggests the correct replacement based on the context + [#10361](https://github.com/rust-lang/rust-clippy/pull/10361) +* [`bool_assert_comparison`]: The suggestion is now machine applicable + [#10218](https://github.com/rust-lang/rust-clippy/pull/10218) +* [`cast_possible_truncation`]: Corrected the lint name in the help message + [#10330](https://github.com/rust-lang/rust-clippy/pull/10330) +* [`needless_return`]: The suggestion now works on if sequences + [#10345](https://github.com/rust-lang/rust-clippy/pull/10345) +* [`needless_lifetimes`]: The suggestion is now machine applicable + [#10222](https://github.com/rust-lang/rust-clippy/pull/10222) +* [`map_entry`]: The suggestion no longer expands macros + [#10346](https://github.com/rust-lang/rust-clippy/pull/10346) + +### ICE Fixes + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +* [`needless_pass_by_value`]: Fixed an ICE caused by how late bounds were handled +======= +* [`needless_pass_by_value`]: Fixed an ICE, caused by how late bounds were handled +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +* [`needless_pass_by_value`]: Fixed an ICE, caused by how late bounds were handled +>>>>>>> 6ce346c94 (Changelog for Rust 1.69 :cherry_blossom:) +======= +* [`needless_pass_by_value`]: Fixed an ICE caused by how late bounds were handled +>>>>>>> 637d10b29 (Catching, stray, commas, (I'll, never, learn, to, use, them, correctly) :sweat_smile:) + [#10328](https://github.com/rust-lang/rust-clippy/pull/10328) +* [`needless_borrow`]: No longer panics on ambiguous projections + [#10403](https://github.com/rust-lang/rust-clippy/pull/10403) + +### Documentation Improvements + +* All configurations are now documented in the Clippy Book + [#10199](https://github.com/rust-lang/rust-clippy/pull/10199) ## Rust 1.68 -Current stable, released 2023-03-09 +Released 2023-03-09 -[d822110d...7f27e2e7](https://github.com/rust-lang/rust-clippy/compare/d822110d...7f27e2e7) +[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-12-01T20%3A40%3A04Z..2023-01-12T18%3A58%3A59Z+base%3Amaster) ### New Lints @@ -159,7 +620,7 @@ Current stable, released 2023-03-09 Released 2023-01-26 -[4f142aa1...d822110d](https://github.com/rust-lang/rust-clippy/compare/4f142aa1...d822110d) +[View all 104 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-10-23T13%3A35%3A19Z..2022-12-01T13%3A34%3A39Z+base%3Amaster) ### New Lints @@ -350,7 +811,7 @@ Released 2023-01-26 Released 2022-12-15 -[b52fb523...4f142aa1](https://github.com/rust-lang/rust-clippy/compare/b52fb523...4f142aa1) +[View all 116 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-09-09T17%3A32%3A39Z..2022-10-23T11%3A27%3A24Z+base%3Amaster) ### New Lints @@ -521,7 +982,7 @@ Released 2022-12-15 Released 2022-11-03 -[3c7e7dbc...b52fb523](https://github.com/rust-lang/rust-clippy/compare/3c7e7dbc...b52fb523) +[View all 86 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-07-29T01%3A09%3A31Z..2022-09-09T00%3A01%3A54Z+base%3Amaster) ### Important Changes @@ -665,7 +1126,7 @@ Released 2022-11-03 Released 2022-09-22 -[d7b5cbf0...3c7e7dbc](https://github.com/rust-lang/rust-clippy/compare/d7b5cbf0...3c7e7dbc) +[View all 110 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-06-17T21%3A25%3A31Z..2022-07-28T17%3A11%3A18Z+base%3Amaster) ### New Lints @@ -815,7 +1276,7 @@ Released 2022-09-22 Released 2022-08-11 -[7c21f91b...d7b5cbf0](https://github.com/rust-lang/rust-clippy/compare/7c21f91b...d7b5cbf0) +[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-05-05T17%3A24%3A22Z..2022-06-16T14%3A24%3A48Z+base%3Amaster) ### New Lints @@ -961,7 +1422,7 @@ Released 2022-08-11 Released 2022-06-30 -[d0cf3481...7c21f91b](https://github.com/rust-lang/rust-clippy/compare/d0cf3481...7c21f91b) +[View all 90 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-03-25T17%3A22%3A30Z..2022-05-05T13%3A29%3A44Z+base%3Amaster) ### New Lints @@ -1118,7 +1579,7 @@ Released 2022-06-30 Released 2022-05-19 -[57b3c4b...d0cf3481](https://github.com/rust-lang/rust-clippy/compare/57b3c4b...d0cf3481) +[View all 60 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-02-11T16%3A54%3A41Z..2022-03-24T13%3A42%3A25Z+base%3Amaster) ### New Lints @@ -1219,7 +1680,7 @@ Released 2022-05-19 Released 2022-04-07 -[0eff589...57b3c4b](https://github.com/rust-lang/rust-clippy/compare/0eff589...57b3c4b) +[View all 73 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-12-31T17%3A53%3A37Z..2022-02-10T17%3A31%3A37Z+base%3Amaster) ### New Lints @@ -1351,7 +1812,7 @@ Released 2022-04-07 Released 2022-02-24 -[e181011...0eff589](https://github.com/rust-lang/rust-clippy/compare/e181011...0eff589) +[View all 94 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-11-04T12%3A40%3A18Z..2021-12-30T13%3A36%3A20Z+base%3Amaster) ### New Lints @@ -1515,7 +1976,7 @@ Released 2022-02-24 Released 2022-01-13 -[00e31fa...e181011](https://github.com/rust-lang/rust-clippy/compare/00e31fa...e181011) +[View all 68 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-10-07T09%3A49%3A18Z..2021-11-04T12%3A20%3A12Z+base%3Amaster) ### Rust 1.58.1 @@ -1636,7 +2097,7 @@ Released 2022-01-13 Released 2021-12-02 -[7bfc26e...00e31fa](https://github.com/rust-lang/rust-clippy/compare/7bfc26e...00e31fa) +[View all 148 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-08-12T20%3A36%3A04Z..2021-11-03T17%3A57%3A59Z+base%3Amaster) ### New Lints @@ -1787,7 +2248,7 @@ Released 2021-12-02 Released 2021-10-21 -[74d1561...7bfc26e](https://github.com/rust-lang/rust-clippy/compare/74d1561...7bfc26e) +[View all 38 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-07-19T14%3A33%3A33Z..2021-08-12T09%3A28%3A38Z+base%3Amaster) ### New Lints @@ -1853,7 +2314,7 @@ Released 2021-10-21 Released 2021-09-09 -[3ae8faf...74d1561](https://github.com/rust-lang/rust-clippy/compare/3ae8faf...74d1561) +[View all 83 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-06-03T07%3A23%3A59Z..2021-07-29T11%3A47%3A32Z+base%3Amaster) ### Important Changes @@ -1971,7 +2432,7 @@ Released 2021-09-09 Released 2021-07-29 -[7c7683c...3ae8faf](https://github.com/rust-lang/rust-clippy/compare/7c7683c...3ae8faf) +[View all 74 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-04-27T23%3A51%3A18Z..2021-06-03T06%3A54%3A07Z+base%3Amaster) ### New Lints @@ -2099,7 +2560,7 @@ Released 2021-07-29 Released 2021-06-17 -[6ed6f1e...7c7683c](https://github.com/rust-lang/rust-clippy/compare/6ed6f1e...7c7683c) +[View all 126 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-03-12T22%3A49%3A20Z..2021-04-27T14%3A38%3A20Z+base%3Amaster) ### New Lints @@ -2283,7 +2744,7 @@ Released 2021-06-17 Released 2021-05-06 -[3e41797...6ed6f1e](https://github.com/rust-lang/rust-clippy/compare/3e41797...6ed6f1e) +[View all 102 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-02-03T15%3A59%3A06Z..2021-03-11T20%3A06%3A43Z+base%3Amaster) ### New Lints @@ -2418,7 +2879,7 @@ Released 2021-05-06 Released 2021-03-25 -[4911ab1...3e41797](https://github.com/rust-lang/rust-clippy/compare/4911ab1...3e41797) +[View all 78 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-12-21T15%3A43%3A04Z..2021-02-03T04%3A21%3A10Z+base%3Amaster) ### New Lints @@ -2533,7 +2994,7 @@ Released 2021-03-25 Released 2021-02-11 -[b20d4c1...4bd77a1](https://github.com/rust-lang/rust-clippy/compare/b20d4c1...4bd77a1) +[View all 119 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-11-06T18%3A32%3A40Z..2021-01-03T14%3A51%3A18Z+base%3Amaster) ### New Lints @@ -2662,7 +3123,7 @@ Released 2021-02-11 Released 2020-12-31 -[e636b88...b20d4c1](https://github.com/rust-lang/rust-clippy/compare/e636b88...b20d4c1) +[View all 107 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-09-24T14%3A05%3A12Z..2020-11-05T13%3A35%3A44Z+base%3Amaster) ### New Lints @@ -2768,7 +3229,7 @@ Released 2020-12-31 Released 2020-11-19 -[09bd400...e636b88](https://github.com/rust-lang/rust-clippy/compare/09bd400...e636b88) +[View all 99 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-08-11T13%3A14%3A38Z..2020-09-23T18%3A55%3A22Z+base%3Amaster) ### New lints @@ -2886,7 +3347,7 @@ Released 2020-11-19 Released 2020-10-08 -[c2c07fa...09bd400](https://github.com/rust-lang/rust-clippy/compare/c2c07fa...09bd400) +[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-06-23T16%3A27%3A11Z..2020-08-11T12%3A52%3A41Z+base%3Amaster) ### New lints @@ -2988,7 +3449,7 @@ Released 2020-10-08 Released 2020-08-27 -[7ea7cd1...c2c07fa](https://github.com/rust-lang/rust-clippy/compare/7ea7cd1...c2c07fa) +[View all 48 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-05-31T12%3A50%3A53Z..2020-06-23T15%3A00%3A32Z+base%3Amaster) ### New lints @@ -3050,7 +3511,7 @@ Released 2020-08-27 Released 2020-07-16 -[891e1a8...7ea7cd1](https://github.com/rust-lang/rust-clippy/compare/891e1a8...7ea7cd1) +[View all 81 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-04-18T20%3A18%3A04Z..2020-05-27T19%3A25%3A04Z+base%3Amaster) ### New lints @@ -3127,7 +3588,7 @@ and [`similar_names`]. [#5651](https://github.com/rust-lang/rust-clippy/pull/565 Released 2020-06-04 -[204bb9b...891e1a8](https://github.com/rust-lang/rust-clippy/compare/204bb9b...891e1a8) +[View all 124 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-03-05T17%3A30%3A53Z..2020-04-18T09%3A20%3A51Z+base%3Amaster) ### New lints @@ -3210,7 +3671,7 @@ Released 2020-06-04 Released 2020-04-23 -[4ee1206...204bb9b](https://github.com/rust-lang/rust-clippy/compare/4ee1206...204bb9b) +[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-01-26T16%3A01%3A11Z..2020-03-04T16%3A45%3A37Z+base%3Amaster) ### New lints @@ -3268,7 +3729,7 @@ Released 2020-04-23 Released 2020-03-12 -[69f99e7...4ee1206](https://github.com/rust-lang/rust-clippy/compare/69f99e7...4ee1206) +[View all 101 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-12-15T01%3A40%3A34Z..2020-01-26T11%3A22%3A13Z+base%3Amaster) ### New lints @@ -3335,7 +3796,7 @@ Released 2020-03-12 Released 2020-01-30 -[c8e3cfb...69f99e7](https://github.com/rust-lang/rust-clippy/compare/c8e3cfb...69f99e7) +[View all 74 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-10-28T20%3A50%3A24Z..2019-12-12T00%3A53%3A03Z+base%3Amaster) * New Lints: * [`exit`] [#4697](https://github.com/rust-lang/rust-clippy/pull/4697) @@ -3380,7 +3841,7 @@ Released 2020-01-30 Released 2019-12-19 -[4e7e71b...c8e3cfb](https://github.com/rust-lang/rust-clippy/compare/4e7e71b...c8e3cfb) +[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-09-23T06%3A18%3A04Z..2019-10-28T17%3A34%3A55Z+base%3Amaster) * New Lints: * [`unneeded_wildcard_pattern`] [#4537](https://github.com/rust-lang/rust-clippy/pull/4537) @@ -3422,7 +3883,7 @@ Released 2019-12-19 Released 2019-11-07 -[3aea860...4e7e71b](https://github.com/rust-lang/rust-clippy/compare/3aea860...4e7e71b) +[View all 100 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-08-11T19%3A21%3A38Z..2019-09-22T12%3A07%3A39Z+base%3Amaster) * New Lints: * [`uninit_assumed_init`] [#4479](https://github.com/rust-lang/rust-clippy/pull/4479) @@ -3466,7 +3927,7 @@ Released 2019-11-07 Released 2019-09-26 -[e3cb40e...3aea860](https://github.com/rust-lang/rust-clippy/compare/e3cb40e...3aea860) +[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-06-30T13%3A40%3A26Z..2019-08-11T09%3A47%3A27Z+base%3Amaster) * New Lints: * [`main_recursion`] [#4203](https://github.com/rust-lang/rust-clippy/pull/4203) @@ -3496,7 +3957,7 @@ Released 2019-09-26 Released 2019-08-15 -[082cfa7...e3cb40e](https://github.com/rust-lang/rust-clippy/compare/082cfa7...e3cb40e) +[View all 72 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-05-19T08%3A11%3A23Z..2019-06-25T23%3A22%3A22Z+base%3Amaster) * New Lints: * [`checked_conversions`] [#4088](https://github.com/rust-lang/rust-clippy/pull/4088) @@ -3520,7 +3981,7 @@ Released 2019-08-15 Released 2019-07-04 -[eb9f9b1...082cfa7](https://github.com/rust-lang/rust-clippy/compare/eb9f9b1...082cfa7) +[View all 81 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-04-10T09%3A41%3A56Z..2019-05-18T00%3A29%3A40Z+base%3Amaster) * New lints: [`find_map`], [`filter_map_next`] [#4039](https://github.com/rust-lang/rust-clippy/pull/4039) * New lint: [`path_buf_push_overwrite`] [#3954](https://github.com/rust-lang/rust-clippy/pull/3954) @@ -3579,7 +4040,7 @@ Released 2019-05-20 Released 2019-04-10 -[1b89724...1fac380](https://github.com/rust-lang/rust-clippy/compare/1b89724...1fac380) +[View all 61 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-01-17T17%3A45%3A39Z..2019-02-19T08%3A24%3A05Z+base%3Amaster) * New lint: [`assertions_on_constants`] to detect for example `assert!(true)` * New lint: [`dbg_macro`] to detect uses of the `dbg!` macro @@ -3609,7 +4070,7 @@ Released 2019-04-10 Released 2019-02-26 -[b2601be...1b89724](https://github.com/rust-lang/rust-clippy/compare/b2601be...1b89724) +[View all 120 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-11-28T06%3A19%3A50Z..2019-01-15T09%3A27%3A02Z+base%3Amaster) * New lints: [`implicit_return`], [`vec_box`], [`cast_ref_to_mut`] * The `rust-clippy` repository is now part of the `rust-lang` org. @@ -3642,7 +4103,7 @@ Released 2019-02-26 Released 2019-01-17 -[2e26fdc2...b2601be](https://github.com/rust-lang/rust-clippy/compare/2e26fdc2...b2601be) +[View all 71 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-10-24T05%3A02%3A21Z..2018-11-27T17%3A29%3A34Z+base%3Amaster) * New lints: [`slow_vector_initialization`], `mem_discriminant_non_enum`, [`redundant_clone`], [`wildcard_dependencies`], @@ -3712,8 +4173,7 @@ Released 2018-12-06 Released 2018-10-25 -[14207503...125907ad](https://github.com/rust-lang/rust-clippy/compare/14207503...125907ad) - +[View all 88 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-08-02T16%3A54%3A12Z..2018-09-17T09%3A44%3A06Z+base%3Amaster) * Deprecate `assign_ops` lint * New lints: [`mistyped_literal_suffixes`], [`ptr_offset_with_cast`], [`needless_collect`], [`copy_iterator`] @@ -4388,6 +4848,7 @@ Released 2018-09-13 [`almost_complete_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range [`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped [`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant +[`arc_with_non_send_sync`]: https://rust-lang.github.io/rust-clippy/master/index.html#arc_with_non_send_sync [`arithmetic_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects [`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions [`as_ptr_cast_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_ptr_cast_mut @@ -4401,6 +4862,7 @@ Released 2018-09-13 [`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock [`await_holding_refcell_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_refcell_ref [`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask +[`big_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#big_endian_bytes [`bind_instead_of_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#bind_instead_of_map [`blacklisted_name`]: https://rust-lang.github.io/rust-clippy/master/index.html#blacklisted_name [`blanket_clippy_restriction_lints`]: https://rust-lang.github.io/rust-clippy/master/index.html#blanket_clippy_restriction_lints @@ -4467,6 +4929,15 @@ Released 2018-09-13 [`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call [`decimal_literal_representation`]: https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation [`declare_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const +<<<<<<< HEAD +<<<<<<< HEAD +[`default_constructed_unit_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_constructed_unit_structs +======= +[`default_constructed_unit_struct`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_constructed_unit_struct +>>>>>>> 942813856 (adds lint to detect construction of unit struct using `default`) +======= +[`default_constructed_unit_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_constructed_unit_structs +>>>>>>> 4e0490363 (rename to plural form) [`default_instead_of_iter_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_instead_of_iter_empty [`default_numeric_fallback`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_numeric_fallback [`default_trait_access`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_trait_access @@ -4494,6 +4965,7 @@ Released 2018-09-13 [`double_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_must_use [`double_neg`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_neg [`double_parens`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_parens +[`drain_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#drain_collect [`drop_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_bounds [`drop_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_copy [`drop_non_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_non_drop @@ -4504,6 +4976,7 @@ Released 2018-09-13 [`else_if_without_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#else_if_without_else [`empty_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_drop [`empty_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enum +[`empty_line_after_doc_comments`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_doc_comments [`empty_line_after_outer_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_outer_attr [`empty_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_loop [`empty_structs_with_brackets`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_structs_with_brackets @@ -4515,6 +4988,15 @@ Released 2018-09-13 [`erasing_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#erasing_op [`err_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#err_expect [`eval_order_dependence`]: https://rust-lang.github.io/rust-clippy/master/index.html#eval_order_dependence +<<<<<<< HEAD +<<<<<<< HEAD +[`excessive_nesting`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting +======= +[`excessive_indentation`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_indentation +>>>>>>> 97c10075e (add the `excessive_*` style lints) +======= +[`excessive_nesting`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting +>>>>>>> e68dbc330 (add `excessive_nesting`) [`excessive_precision`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_precision [`exhaustive_enums`]: https://rust-lang.github.io/rust-clippy/master/index.html#exhaustive_enums [`exhaustive_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#exhaustive_structs @@ -4569,6 +5051,7 @@ Released 2018-09-13 [`get_first`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_first [`get_last_with_len`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_last_with_len [`get_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_unwrap +[`host_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#host_endian_bytes [`identity_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#identity_conversion [`identity_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#identity_op [`if_let_mutex`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_mutex @@ -4587,6 +5070,8 @@ Released 2018-09-13 [`imprecise_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#imprecise_flops [`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping [`inconsistent_struct_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor +[`incorrect_clone_impl_on_copy_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_clone_impl_on_copy_type +[`incorrect_partial_ord_impl_on_ord_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_partial_ord_impl_on_ord_type [`index_refutable_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice [`indexing_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing [`ineffective_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_bit_mask @@ -4615,6 +5100,7 @@ Released 2018-09-13 [`invisible_characters`]: https://rust-lang.github.io/rust-clippy/master/index.html#invisible_characters [`is_digit_ascii_radix`]: https://rust-lang.github.io/rust-clippy/master/index.html#is_digit_ascii_radix [`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements +[`items_after_test_module`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_test_module [`iter_cloned_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_cloned_collect [`iter_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_count [`iter_kv_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map @@ -4629,6 +5115,7 @@ Released 2018-09-13 [`iter_skip_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_next [`iter_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_with_drain [`iterator_step_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iterator_step_by_zero +[`join_absolute_paths`]: https://rust-lang.github.io/rust-clippy/master/index.html#join_absolute_paths [`just_underscores_and_digits`]: https://rust-lang.github.io/rust-clippy/master/index.html#just_underscores_and_digits [`large_const_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays [`large_digit_groups`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_digit_groups @@ -4636,6 +5123,7 @@ Released 2018-09-13 [`large_futures`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_futures [`large_include_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file [`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays +[`large_stack_frames`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames [`large_types_passed_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value [`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty [`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero @@ -4649,6 +5137,7 @@ Released 2018-09-13 [`let_with_type_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_with_type_underscore [`lines_filter_map_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok [`linkedlist`]: https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist +[`little_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#little_endian_bytes [`logic_bug`]: https://rust-lang.github.io/rust-clippy/master/index.html#logic_bug [`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#lossy_float_literal [`macro_use_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#macro_use_imports @@ -4664,13 +5153,25 @@ Released 2018-09-13 [`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten [`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed [`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check +[`manual_is_finite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_finite +[`manual_is_infinite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_infinite [`manual_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else [`manual_main_separator_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_main_separator_str [`manual_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_map [`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy +[`manual_next_back`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_next_back [`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive [`manual_ok_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_or [`manual_range_contains`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains +<<<<<<< HEAD +<<<<<<< HEAD +[`manual_range_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_patterns +======= +[`manual_range_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_pattern +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) +======= +[`manual_range_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_patterns +>>>>>>> b592d3996 (manual_range_pattern -> manual_range_patterns) [`manual_rem_euclid`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid [`manual_retain`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain [`manual_saturating_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_saturating_arithmetic @@ -4680,7 +5181,9 @@ Released 2018-09-13 [`manual_string_new`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_string_new [`manual_strip`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip [`manual_swap`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_swap +[`manual_try_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold [`manual_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or +[`manual_while_let_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_while_let_some [`many_single_char_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names [`map_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_clone [`map_collect_result_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_collect_result_unit @@ -4702,11 +5205,13 @@ Released 2018-09-13 [`match_wild_err_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wild_err_arm [`match_wildcard_for_single_variants`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants [`maybe_infinite_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#maybe_infinite_iter +[`maybe_misused_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#maybe_misused_cfg [`mem_discriminant_non_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_discriminant_non_enum [`mem_forget`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_forget [`mem_replace_option_with_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_none [`mem_replace_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default [`mem_replace_with_uninit`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_uninit +[`min_ident_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars [`min_max`]: https://rust-lang.github.io/rust-clippy/master/index.html#min_max [`misaligned_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#misaligned_transmute [`mismatched_target_os`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatched_target_os @@ -4718,6 +5223,7 @@ Released 2018-09-13 [`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items [`missing_enforced_import_renames`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames [`missing_errors_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc +[`missing_fields_in_debug`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_fields_in_debug [`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_inline_in_public_items [`missing_panics_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc [`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc @@ -4748,21 +5254,35 @@ Released 2018-09-13 [`needless_arbitrary_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_arbitrary_self_type [`needless_bitwise_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bitwise_bool [`needless_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool +[`needless_bool_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool_assign [`needless_borrow`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow [`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference [`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect [`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue [`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main +[`needless_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_else [`needless_for_each`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_for_each +[`needless_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_if [`needless_late_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init [`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes [`needless_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_match [`needless_option_as_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_as_deref [`needless_option_take`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_take [`needless_parens_on_range_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_parens_on_range_literals +[`needless_pass_by_ref_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut [`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value +[`needless_pub_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pub_self [`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark [`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop +[`needless_raw_string_hashes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes +<<<<<<< HEAD +<<<<<<< HEAD +[`needless_raw_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_strings +======= +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= +[`needless_raw_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_strings +>>>>>>> 8cb6c8699 (change category and refactor) [`needless_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return [`needless_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_splitn [`needless_update`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_update @@ -4778,6 +5298,7 @@ Released 2018-09-13 [`no_effect_underscore_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_effect_underscore_binding [`no_mangle_with_rust_abi`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_mangle_with_rust_abi [`non_ascii_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_ascii_literal +[`non_minimal_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_minimal_cfg [`non_octal_unix_permissions`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_octal_unix_permissions [`non_send_fields_in_send_ty`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty [`nonminimal_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool @@ -4814,7 +5335,6 @@ Released 2018-09-13 [`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl [`partialeq_to_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_to_none [`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_buf_push_overwrite -[`path_join_correction`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_join_correction [`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#pattern_type_mismatch [`permissions_set_readonly_false`]: https://rust-lang.github.io/rust-clippy/master/index.html#permissions_set_readonly_false [`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#positional_named_format_parameters @@ -4828,10 +5348,13 @@ Released 2018-09-13 [`println_empty_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#println_empty_string [`ptr_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg [`ptr_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr +[`ptr_cast_constness`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_cast_constness [`ptr_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_eq [`ptr_offset_with_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_with_cast [`pub_enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_enum_variant_names [`pub_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_use +[`pub_with_shorthand`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_with_shorthand +[`pub_without_shorthand`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_without_shorthand [`question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark [`question_mark_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark_used [`range_minus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_minus_one @@ -4841,10 +5364,12 @@ Released 2018-09-13 [`rc_buffer`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer [`rc_clone_in_vec_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_clone_in_vec_init [`rc_mutex`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex +[`read_line_without_trim`]: https://rust-lang.github.io/rust-clippy/master/index.html#read_line_without_trim [`read_zero_byte_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#read_zero_byte_vec [`recursive_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#recursive_format_impl [`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation [`redundant_async_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_async_block +[`redundant_at_rest_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_at_rest_pattern [`redundant_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone [`redundant_closure`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure [`redundant_closure_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_call @@ -4857,9 +5382,11 @@ Released 2018-09-13 [`redundant_pub_crate`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pub_crate [`redundant_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_slicing [`redundant_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes +[`redundant_type_annotations`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_type_annotations [`ref_binding_to_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_binding_to_reference [`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref [`ref_option_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option_ref +[`ref_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_patterns [`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro [`repeat_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_once [`replace_consts`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_consts @@ -4896,6 +5423,7 @@ Released 2018-09-13 [`significant_drop_in_scrutinee`]: https://rust-lang.github.io/rust-clippy/master/index.html#significant_drop_in_scrutinee [`significant_drop_tightening`]: https://rust-lang.github.io/rust-clippy/master/index.html#significant_drop_tightening [`similar_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#similar_names +[`single_call_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn [`single_char_add_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_add_str [`single_char_lifetime_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_lifetime_names [`single_char_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern @@ -4904,6 +5432,7 @@ Released 2018-09-13 [`single_element_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_element_loop [`single_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match [`single_match_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match_else +[`single_range_in_vec_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_range_in_vec_init [`size_of_in_element_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#size_of_in_element_count [`size_of_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#size_of_ref [`skip_while_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#skip_while_next @@ -4966,7 +5495,9 @@ Released 2018-09-13 [`trivial_regex`]: https://rust-lang.github.io/rust-clippy/master/index.html#trivial_regex [`trivially_copy_pass_by_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref [`try_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#try_err +[`tuple_array_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions [`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity +[`type_id_on_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_id_on_box [`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds [`unchecked_duration_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction [`undocumented_unsafe_blocks`]: https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks @@ -4988,6 +5519,7 @@ Released 2018-09-13 [`unnecessary_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fold [`unnecessary_join`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_join [`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations +[`unnecessary_literal_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_unwrap [`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed [`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation [`unnecessary_owned_empty_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_owned_empty_strings @@ -5061,3 +5593,83 @@ Released 2018-09-13 [`zero_width_space`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_width_space [`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset + +[`arithmetic-side-effects-allowed`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed +[`arithmetic-side-effects-allowed-binary`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed-binary +[`arithmetic-side-effects-allowed-unary`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed-unary +[`avoid-breaking-exported-api`]: https://doc.rust-lang.org/clippy/lint_configuration.html#avoid-breaking-exported-api +[`msrv`]: https://doc.rust-lang.org/clippy/lint_configuration.html#msrv +[`cognitive-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cognitive-complexity-threshold +[`excessive-nesting-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#excessive-nesting-threshold +[`disallowed-names`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-names +[`semicolon-inside-block-ignore-singleline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-inside-block-ignore-singleline +[`semicolon-outside-block-ignore-multiline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-outside-block-ignore-multiline +[`doc-valid-idents`]: https://doc.rust-lang.org/clippy/lint_configuration.html#doc-valid-idents +[`too-many-arguments-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-arguments-threshold +[`type-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#type-complexity-threshold +[`single-char-binding-names-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#single-char-binding-names-threshold +[`too-large-for-stack`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-large-for-stack +[`enum-variant-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-name-threshold +[`enum-variant-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-size-threshold +[`verbose-bit-mask-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#verbose-bit-mask-threshold +[`literal-representation-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#literal-representation-threshold +[`trivial-copy-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#trivial-copy-size-limit +[`pass-by-value-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pass-by-value-size-limit +[`too-many-lines-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-lines-threshold +[`array-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#array-size-threshold +[`stack-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#stack-size-threshold +[`vec-box-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#vec-box-size-threshold +[`max-trait-bounds`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-trait-bounds +[`max-struct-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-struct-bools +[`max-fn-params-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-fn-params-bools +[`warn-on-all-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#warn-on-all-wildcard-imports +[`disallowed-macros`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-macros +[`disallowed-methods`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-methods +[`disallowed-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-types +[`unreadable-literal-lint-fractions`]: https://doc.rust-lang.org/clippy/lint_configuration.html#unreadable-literal-lint-fractions +[`upper-case-acronyms-aggressive`]: https://doc.rust-lang.org/clippy/lint_configuration.html#upper-case-acronyms-aggressive +[`matches-for-let-else`]: https://doc.rust-lang.org/clippy/lint_configuration.html#matches-for-let-else +[`cargo-ignore-publish`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cargo-ignore-publish +[`standard-macro-braces`]: https://doc.rust-lang.org/clippy/lint_configuration.html#standard-macro-braces +[`enforced-import-renames`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforced-import-renames +[`allowed-scripts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-scripts +[`enable-raw-pointer-heuristic-for-send`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enable-raw-pointer-heuristic-for-send +[`max-suggested-slice-pattern-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-suggested-slice-pattern-length +[`await-holding-invalid-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#await-holding-invalid-types +[`max-include-file-size`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-include-file-size +[`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests +[`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests +[`allow-dbg-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-dbg-in-tests +[`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests +[`large-error-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-threshold +[`ignore-interior-mutability`]: https://doc.rust-lang.org/clippy/lint_configuration.html#ignore-interior-mutability +[`allow-mixed-uninlined-format-args`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-mixed-uninlined-format-args +[`suppress-restriction-lint-in-const`]: https://doc.rust-lang.org/clippy/lint_configuration.html#suppress-restriction-lint-in-const +[`missing-docs-in-crate-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-in-crate-items +[`future-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#future-size-threshold +[`unnecessary-box-size`]: https://doc.rust-lang.org/clippy/lint_configuration.html#unnecessary-box-size +[`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception +[`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars +[`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold +<<<<<<< HEAD +<<<<<<< HEAD +[`accept-comment-above-statement`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-statement +[`accept-comment-above-attributes`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-attributes +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +[`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings +======= +>>>>>>> d5b2f1134 (Now `cargo collect-metadata` updates the `CHANGELOG.md`) +======= +[`accept-comment-above-statement`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-statement +>>>>>>> d6102018b (Collecting metadata) +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) +======= +[`allow-one-hash-in-raw-string`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-string +>>>>>>> cb52d19ce (don't lint `needless_raw_string_hashes` when it's unnecessary) +======= +[`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings +>>>>>>> 8cb6c8699 (change category and refactor) + diff --git a/Cargo.toml b/Cargo.toml index 5bb9f527081e..b31e7d7f16ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,10 @@ [package] name = "clippy" -version = "0.1.70" +<<<<<<< HEAD +version = "0.1.73" +======= +version = "0.1.71" +>>>>>>> e4f5d83fa (Fixed formatting.) description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" @@ -22,38 +26,46 @@ path = "src/driver.rs" [dependencies] clippy_lints = { path = "clippy_lints" } -semver = "1.0" rustc_tools_util = "0.3.0" tempfile = { version = "3.2", optional = true } termize = "0.1" [dev-dependencies] -compiletest_rs = { version = "0.9", features = ["tmp"] } +<<<<<<< HEAD +ui_test = "0.11.5" +======= +compiletest_rs = { version = "0.10", features = ["tmp"] } +>>>>>>> e4f5d83fa (Fixed formatting.) tester = "0.9" regex = "1.5" -toml = "0.5" +toml = "0.7.3" walkdir = "2.3" # This is used by the `collect-metadata` alias. filetime = "0.2" - -# A noop dependency that changes in the Rust repository, it's a bit of a hack. -# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust` -# for more information. -rustc-workspace-hack = "1.0" +<<<<<<< HEAD +<<<<<<< HEAD +======= # UI test dependencies clap = { version = "4.1.4", features = ["derive"] } clippy_utils = { path = "clippy_utils" } derive-new = "0.5" if_chain = "1.0" +>>>>>>> 066037b62 (actually, remove rustc-workspace-hack dependency too) +======= +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) itertools = "0.10.1" + +# UI test dependencies +clippy_utils = { path = "clippy_utils" } +derive-new = "0.5" +if_chain = "1.0" quote = "1.0" serde = { version = "1.0.125", features = ["derive"] } syn = { version = "2.0", features = ["full"] } futures = "0.3" parking_lot = "0.12" tokio = { version = "1", features = ["io-util"] } -rustc-semver = "1.1" [build-dependencies] rustc_tools_util = "0.3.0" @@ -66,3 +78,7 @@ internal = ["clippy_lints/internal", "tempfile"] [package.metadata.rust-analyzer] # This package uses #[feature(rustc_private)] rustc_private = true + +[[test]] +name = "compile-test" +harness = false diff --git a/README.md b/README.md index 85798e0e80c1..5d490645d897 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are over 600 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are over 650 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category. @@ -91,7 +91,8 @@ cargo clippy #### Automatically applying Clippy suggestions -Clippy can automatically apply some lint suggestions, just like the compiler. +Clippy can automatically apply some lint suggestions, just like the compiler. Note that `--fix` implies +`--all-targets`, so it can fix as much code as it can. ```terminal cargo clippy --fix @@ -277,7 +278,7 @@ If you want to contribute to Clippy, you can find more information in [CONTRIBUT -Copyright 2014-2022 The Rust Project Developers +Copyright 2014-2023 The Rust Project Developers Licensed under the Apache License, Version 2.0 or the MIT license diff --git a/book/src/README.md b/book/src/README.md index 3b6270962680..486ea3df7042 100644 --- a/book/src/README.md +++ b/book/src/README.md @@ -6,7 +6,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are over 600 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are over 650 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 22fbdce75e8f..980c9115494f 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -13,9 +13,35 @@ - [Development](development/README.md) - [Basics](development/basics.md) - [Adding Lints](development/adding_lints.md) +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) - [Lint Passes](development/lint_passes.md) - [Type Checking](development/type_checking.md) - [Macro Expansions](development/macro_expansions.md) +======= + - [Type Checking](development/type_checking.md) +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + - [Lint Passes](development/lint_passes.md) + - [Type Checking](development/type_checking.md) + - [Macro Expansions](development/macro_expansions.md) +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +<<<<<<< HEAD +======= + - [Type Checking](development/type_checking.md) +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + - [Lint Passes](development/lint_passes.md) + - [Type Checking](development/type_checking.md) + - [Macro Expansions](development/macro_expansions.md) +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) - [Common Tools](development/common_tools_writing_lints.md) - [Infrastructure](development/infrastructure/README.md) - [Syncing changes between Clippy and rust-lang/rust](development/infrastructure/sync.md) diff --git a/book/src/configuration.md b/book/src/configuration.md index 1304f6a8c2f0..eb4f946977d8 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -2,8 +2,27 @@ > **Note:** The configuration file is unstable and may be deprecated in the future. -Some lints can be configured in a TOML file named `clippy.toml` or `.clippy.toml`. It contains a -basic `variable = value` mapping e.g. +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 194343fce (Explain path-search using a list) +Some lints can be configured in a TOML file named `clippy.toml` or `.clippy.toml`, which is searched for in: + +1. The directory specified by the `CLIPPY_CONF_DIR` environment variable, or +2. The directory specified by the +[CARGO_MANIFEST_DIR](https://doc.rust-lang.org/cargo/reference/environment-variables.html) environment variable, or +3. The current directory. + +It contains a basic `variable = value` mapping e.g. +<<<<<<< HEAD +======= +Some lints can be configured in a TOML file named `clippy.toml` or `.clippy.toml`, placed in a directory specified by +the environment variable `CLIPPY_CONF_DIR`, or if that's not found, the environment variable +[CARGO_MANIFEST_DIR](https://doc.rust-lang.org/cargo/reference/environment-variables.html), or if that isn't +found, the current directory. It contains a basic `variable = value` mapping e.g. +>>>>>>> 5f5e2e2ac (Explain which paths clippy searches for configuration in docs) +======= +>>>>>>> 194343fce (Explain path-search using a list) ```toml avoid-breaking-exported-api = false diff --git a/book/src/development/adding_lints.md b/book/src/development/adding_lints.md index 9dacaaaae5c9..fa2b1e7e414b 100644 --- a/book/src/development/adding_lints.md +++ b/book/src/development/adding_lints.md @@ -122,20 +122,17 @@ fn main() { } ``` -Now we can run the test with `TESTNAME=foo_functions cargo uitest`, currently +Now we can run the test with `TESTNAME=foo_functions cargo uibless`, currently this test is meaningless though. While we are working on implementing our lint, we can keep running the UI test. -That allows us to check if the output is turning into what we want. +That allows us to check if the output is turning into what we want by checking the +`.stderr` file that gets updated on every test run. -Once we are satisfied with the output, we need to run `cargo dev bless` to -update the `.stderr` file for our lint. Please note that, we should run -`TESTNAME=foo_functions cargo uitest` every time before running `cargo dev -bless`. Running `TESTNAME=foo_functions cargo uitest` should pass then. When we +Running `TESTNAME=foo_functions cargo uitest` should pass on its own. When we commit our lint, we need to commit the generated `.stderr` files, too. In -general, you should only commit files changed by `cargo dev bless` for the -specific lint you are creating/editing. Note that if the generated files are -empty, they should be removed. +general, you should only commit files changed by `cargo bless` for the +specific lint you are creating/editing. > _Note:_ you can run multiple test files by specifying a comma separated list: > `TESTNAME=foo_functions,test2,test3`. @@ -164,12 +161,12 @@ The process of generating the `.stderr` file is the same, and prepending the ## Rustfix tests If the lint you are working on is making use of structured suggestions, the test -file should include a `// run-rustfix` comment at the top. This will +file should include a `//@run-rustfix` comment at the top. This will additionally run [rustfix] for that test. Rustfix will apply the suggestions from the lint to the code of the test file and compare that to the contents of a `.fixed` file. -Use `cargo dev bless` to automatically generate the `.fixed` file after running +Use `cargo bless` to automatically generate the `.fixed` file while running the tests. [rustfix]: https://github.com/rust-lang/rustfix @@ -417,7 +414,7 @@ fn is_foo_fn(fn_kind: FnKind<'_>) -> bool { Now we should also run the full test suite with `cargo test`. At this point running `cargo test` should produce the expected output. Remember to run `cargo -dev bless` to update the `.stderr` file. +bless` to update the `.stderr` file. `cargo test` (as opposed to `cargo uitest`) will also ensure that our lint implementation is not violating any Clippy lints itself. @@ -630,8 +627,27 @@ Before submitting your PR make sure you followed all the basic requirements: ## Adding configuration to a lint -Clippy supports the configuration of lints values using a `clippy.toml` file in -the workspace directory. Adding a configuration to a lint can be useful for +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 194343fce (Explain path-search using a list) +Clippy supports the configuration of lints values using a `clippy.toml` file which is searched for in: + +1. The directory specified by the `CLIPPY_CONF_DIR` environment variable, or +2. The directory specified by the +[CARGO_MANIFEST_DIR](https://doc.rust-lang.org/cargo/reference/environment-variables.html) environment variable, or +3. The current directory. + +Adding a configuration to a lint can be useful for +<<<<<<< HEAD +======= +Clippy supports the configuration of lints values using a `clippy.toml` file in a directory specified by +the environment variable `CLIPPY_CONF_DIR`, or if that's not found, the environment variable +[CARGO_MANIFEST_DIR](https://doc.rust-lang.org/cargo/reference/environment-variables.html), or if that isn't +found, the current directory. Adding a configuration to a lint can be useful for +>>>>>>> 5f5e2e2ac (Explain which paths clippy searches for configuration in docs) +======= +>>>>>>> 194343fce (Explain path-search using a list) thresholds or to constrain some behavior that can be seen as a false positive for some users. Adding a configuration is done in the following steps: diff --git a/book/src/development/basics.md b/book/src/development/basics.md index 7615dc12f9eb..f4c109ff1191 100644 --- a/book/src/development/basics.md +++ b/book/src/development/basics.md @@ -66,7 +66,7 @@ If the output of a [UI test] differs from the expected output, you can update the reference file with: ```bash -cargo dev bless +cargo bless ``` For example, this is necessary if you fix a typo in an error message of a lint, diff --git a/book/src/development/lint_passes.md b/book/src/development/lint_passes.md index c41b6ea0de8f..c32fd04fca30 100644 --- a/book/src/development/lint_passes.md +++ b/book/src/development/lint_passes.md @@ -50,7 +50,34 @@ questions already, but the parser is okay with it. This is what we mean when we say `EarlyLintPass` deals with only syntax on the AST level. Alternatively, think of the `foo_functions` lint we mentioned in +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +define new lints chapter. +======= +define new lints chapter. +>>>>>>> d1f55e6b5 (run linkcheck in Remark CI) +======= [define new lints](define_lints.md#name-the-lint) chapter. +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +define new lints chapter. +>>>>>>> 6c859b6d2 (Clippy book: hotfix for broken link) +======= +define new lints chapter. +>>>>>>> d1f55e6b5 (run linkcheck in Remark CI) +======= +define new lints chapter. +======= +<<<<<<< HEAD +define new lints chapter. +======= +define new lints chapter. +>>>>>>> d1f55e6b5 (run linkcheck in Remark CI) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) We want the `foo_functions` lint to detect functions with `foo` as their name. Writing a lint that only checks for the name of a function means that we only diff --git a/book/src/development/proposals/syntax-tree-patterns.md b/book/src/development/proposals/syntax-tree-patterns.md index 36d722609f4a..285488cec55c 100644 --- a/book/src/development/proposals/syntax-tree-patterns.md +++ b/book/src/development/proposals/syntax-tree-patterns.md @@ -139,7 +139,7 @@ whether the pattern matched. ## Pattern syntax -The following examples demonstate the pattern syntax: +The following examples demonstrate the pattern syntax: #### Any (`_`) diff --git a/book/src/development/speedtest.md b/book/src/development/speedtest.md new file mode 100644 index 000000000000..0db718e6ad67 --- /dev/null +++ b/book/src/development/speedtest.md @@ -0,0 +1,24 @@ +# Speedtest +`SPEEDTEST` is the tool we use to measure lint's performance, it works by executing the same test several times. + +It's useful for measuring changes to current lints and deciding if the performance changes too much. `SPEEDTEST` is +accessed by the `SPEEDTEST` (and `SPEEDTEST_*`) environment variables. + +## Checking Speedtest + +To do a simple speed test of a lint (e.g. `allow_attributes`), use this command. + +```sh +$ SPEEDTEST=ui TESTNAME="allow_attributes" cargo uitest -- --nocapture +``` + +This will test all `ui` tests (`SPEEDTEST=ui`) whose names start with `allow_attributes`. By default, `SPEEDTEST` will +iterate your test 1000 times. But you can change this with `SPEEDTEST_ITERATIONS`. + +```sh +$ SPEEDTEST=toml SPEEDTEST_ITERATIONS=100 TESTNAME="semicolon_block" cargo uitest -- --nocapture +``` + +> **WARNING**: Be sure to use `-- --nocapture` at the end of the command to see the average test time. If you don't +> use `-- --nocapture` (e.g. `SPEEDTEST=ui` `TESTNAME="let_underscore_untyped" cargo uitest -- --nocapture`), this +> will not show up. diff --git a/book/src/development/type_checking.md b/book/src/development/type_checking.md index 225de8495662..aa8029bbf58f 100644 --- a/book/src/development/type_checking.md +++ b/book/src/development/type_checking.md @@ -51,7 +51,29 @@ impl LateLintPass<'_> for MyStructLint { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { // Get type of `expr` let ty = cx.typeck_results().expr_ty(expr); - +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) + +======= + +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +<<<<<<< HEAD +======= + +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) // Check if the `Ty` of this expression is of character type if ty.is_char() { println!("Our expression is a char!"); @@ -70,18 +92,79 @@ pub fn is_char(self) -> bool { } ``` +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) +Indeed, we just discovered `Ty`'s [`kind()` method][kind], which provides us +======= +Indeed, we just discovered `Ty`'s [`kind` method][kind], which provides us +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +Indeed, we just discovered `Ty`'s [`kind()` method][kind], which provides us +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +<<<<<<< HEAD +======= +Indeed, we just discovered `Ty`'s [`kind` method][kind], which provides us +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= Indeed, we just discovered `Ty`'s [`kind()` method][kind], which provides us +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) with [`TyKind`][TyKind] of a `Ty`. ## `TyKind` `TyKind` defines the kinds of types in Rust's type system. Peeking into [`TyKind` documentation][TyKind], we will see that it is an +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) +enum of over 25 variants, including items such as `Bool`, `Int`, `Ref`, etc. + +### `kind` Usage + +The `TyKind` of `Ty` can be returned by calling [`Ty.kind()` method][kind]. +======= +<<<<<<< HEAD +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) +enum of 27 variants, including items such as `Bool`, `Int`, `Ref`, etc. + +### `kind` Usage + +The `TyKind` of `Ty` can be returned by calling [`Ty.kind` method][kind]. +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +enum of over 25 variants, including items such as `Bool`, `Int`, `Ref`, etc. + +### `kind` Usage + +The `TyKind` of `Ty` can be returned by calling [`Ty.kind()` method][kind]. +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= enum of over 25 variants, including items such as `Bool`, `Int`, `Ref`, etc. ### `kind` Usage The `TyKind` of `Ty` can be returned by calling [`Ty.kind()` method][kind]. +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) We often use this method to perform pattern matching in Clippy. For instance, if we want to check for a `struct`, we could examine if the @@ -107,8 +190,61 @@ impl LateLintPass<'_> for MyStructLint { We've been talking about [`ty::Ty`][middle_ty] this whole time without addressing [`hir::Ty`][hir_ty], but the latter is also important to understand. +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) +`hir::Ty` would represent *what* the user wrote, while `ty::Ty` is how the compiler sees the type and has more +information. Example: + +```rust +fn foo(x: u32) -> u32 { x } +``` + +Here the HIR sees the types without "thinking" about them, it knows that the function takes an `u32` and returns +an `u32`. As far as `hir::Ty` is concerned those might be different types. But at the `ty::Ty` level the compiler +understands that they're the same type, in-depth lifetimes, etc... + +To get from a `hir::Ty` to a `ty::Ty`, you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function outside of bodies or +outside of bodies the [`TypeckResults::node_type()`][node_type] method. + +> **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs. +======= +`hir::Ty` would represent *what* an user wrote, while `ty::Ty` would understand the meaning of it (because it has more +information). +======= +`hir::Ty` would represent *what* the user wrote, while `ty::Ty` is how the compiler sees the type and has more +information. Example: +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) + +```rust +fn foo(x: u32) -> u32 { x } +``` + +Here the HIR sees the types without "thinking" about them, it knows that the function takes an `u32` and returns +an `u32`. As far as `hir::Ty` is concerned those might be different types. But at the `ty::Ty` level the compiler +understands that they're the same type, in-depth lifetimes, etc... + +<<<<<<< HEAD +you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function to convert from a `hir::Ty` to a `ty::Ty` +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +To get from a `hir::Ty` to a `ty::Ty`, you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function outside of bodies or +outside of bodies the [`TypeckResults::node_type()`][node_type] method. + +> **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs. +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +<<<<<<< HEAD +======= +`hir::Ty` would represent *what* an user wrote, while `ty::Ty` would understand the meaning of it (because it has more +information). +======= `hir::Ty` would represent *what* the user wrote, while `ty::Ty` is how the compiler sees the type and has more information. Example: +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) ```rust fn foo(x: u32) -> u32 { x } @@ -118,10 +254,17 @@ Here the HIR sees the types without "thinking" about them, it knows that the fun an `u32`. As far as `hir::Ty` is concerned those might be different types. But at the `ty::Ty` level the compiler understands that they're the same type, in-depth lifetimes, etc... +<<<<<<< HEAD +you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function to convert from a `hir::Ty` to a `ty::Ty` +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= To get from a `hir::Ty` to a `ty::Ty`, you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function outside of bodies or outside of bodies the [`TypeckResults::node_type()`][node_type] method. > **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs. +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) ## Useful Links @@ -133,18 +276,38 @@ in this chapter: - [Type checking](https://rustc-dev-guide.rust-lang.org/type-checking.html) - [Ty module](https://rustc-dev-guide.rust-lang.org/ty.html) -[Adt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Adt +[Adt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/sty/enum.TyKind.html#variant.Adt [AdtDef]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/adt/struct.AdtDef.html [expr_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.expr_ty +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) +[node_type]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.node_type +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +[node_type]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.node_type +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +<<<<<<< HEAD +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= [node_type]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.node_type +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) [is_char]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.is_char [is_char_source]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_middle/ty/sty.rs.html#1831-1834 [kind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.kind [LateContext]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LateContext.html [LateLintPass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html -[pat_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TypeckResults.html#method.pat_ty +[pat_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/typeck_results/struct.TypeckResults.html#method.pat_ty [Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html -[TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html +[TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/sty/enum.TyKind.html [TypeckResults]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html [middle_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_middle/ty/struct.Ty.html [hir_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/struct.Ty.html diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 78e1a55cff32..e50dfadd05e0 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -3,6 +3,8 @@ This file is generated by `cargo collect-metadata`. Please use that command to update the file and do not edit it by hand. --> +<<<<<<< HEAD +<<<<<<< HEAD ## Lint Configuration Options |
Option
| Default Value | |--|--| @@ -13,6 +15,8 @@ Please use that command to update the file and do not edit it by hand. | [msrv](#msrv) | `None` | | [cognitive-complexity-threshold](#cognitive-complexity-threshold) | `25` | | [disallowed-names](#disallowed-names) | `["foo", "baz", "quux"]` | +| [semicolon-inside-block-ignore-singleline](#semicolon-inside-block-ignore-singleline) | `false` | +| [semicolon-outside-block-ignore-multiline](#semicolon-outside-block-ignore-multiline) | `false` | | [doc-valid-idents](#doc-valid-idents) | `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` | | [too-many-arguments-threshold](#too-many-arguments-threshold) | `7` | | [type-complexity-threshold](#type-complexity-threshold) | `250` | @@ -55,8 +59,88 @@ Please use that command to update the file and do not edit it by hand. | [suppress-restriction-lint-in-const](#suppress-restriction-lint-in-const) | `false` | | [missing-docs-in-crate-items](#missing-docs-in-crate-items) | `false` | | [future-size-threshold](#future-size-threshold) | `16384` | +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +| [unnecessary-box-size](#unnecessary-box-size) | `128` | +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +| [unnecessary-box-size](#unnecessary-box-size) | `128` | +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +| [unnecessary-box-size](#unnecessary-box-size) | `128` | +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) +======= +# Lint Configuration Options +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +# Lint Configuration Options +======= +## Lint Configuration Options +|
Option
| Default Value | +|--|--| +| [arithmetic-side-effects-allowed](#arithmetic-side-effects-allowed) | `{}` | +| [arithmetic-side-effects-allowed-binary](#arithmetic-side-effects-allowed-binary) | `[]` | +| [arithmetic-side-effects-allowed-unary](#arithmetic-side-effects-allowed-unary) | `{}` | +| [avoid-breaking-exported-api](#avoid-breaking-exported-api) | `true` | +| [msrv](#msrv) | `None` | +| [cognitive-complexity-threshold](#cognitive-complexity-threshold) | `25` | +| [disallowed-names](#disallowed-names) | `["foo", "baz", "quux"]` | +| [semicolon-inside-block-ignore-singleline](#semicolon-inside-block-ignore-singleline) | `false` | +| [semicolon-outside-block-ignore-multiline](#semicolon-outside-block-ignore-multiline) | `false` | +| [doc-valid-idents](#doc-valid-idents) | `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` | +| [too-many-arguments-threshold](#too-many-arguments-threshold) | `7` | +| [type-complexity-threshold](#type-complexity-threshold) | `250` | +| [single-char-binding-names-threshold](#single-char-binding-names-threshold) | `4` | +| [too-large-for-stack](#too-large-for-stack) | `200` | +| [enum-variant-name-threshold](#enum-variant-name-threshold) | `3` | +| [enum-variant-size-threshold](#enum-variant-size-threshold) | `200` | +| [verbose-bit-mask-threshold](#verbose-bit-mask-threshold) | `1` | +| [literal-representation-threshold](#literal-representation-threshold) | `16384` | +| [trivial-copy-size-limit](#trivial-copy-size-limit) | `None` | +| [pass-by-value-size-limit](#pass-by-value-size-limit) | `256` | +| [too-many-lines-threshold](#too-many-lines-threshold) | `100` | +| [array-size-threshold](#array-size-threshold) | `512000` | +| [vec-box-size-threshold](#vec-box-size-threshold) | `4096` | +| [max-trait-bounds](#max-trait-bounds) | `3` | +| [max-struct-bools](#max-struct-bools) | `3` | +| [max-fn-params-bools](#max-fn-params-bools) | `3` | +| [warn-on-all-wildcard-imports](#warn-on-all-wildcard-imports) | `false` | +| [disallowed-macros](#disallowed-macros) | `[]` | +| [disallowed-methods](#disallowed-methods) | `[]` | +| [disallowed-types](#disallowed-types) | `[]` | +| [unreadable-literal-lint-fractions](#unreadable-literal-lint-fractions) | `true` | +| [upper-case-acronyms-aggressive](#upper-case-acronyms-aggressive) | `false` | +| [matches-for-let-else](#matches-for-let-else) | `WellKnownTypes` | +| [cargo-ignore-publish](#cargo-ignore-publish) | `false` | +| [standard-macro-braces](#standard-macro-braces) | `[]` | +| [enforced-import-renames](#enforced-import-renames) | `[]` | +| [allowed-scripts](#allowed-scripts) | `["Latin"]` | +| [enable-raw-pointer-heuristic-for-send](#enable-raw-pointer-heuristic-for-send) | `true` | +| [max-suggested-slice-pattern-length](#max-suggested-slice-pattern-length) | `3` | +| [await-holding-invalid-types](#await-holding-invalid-types) | `[]` | +| [max-include-file-size](#max-include-file-size) | `1000000` | +| [allow-expect-in-tests](#allow-expect-in-tests) | `false` | +| [allow-unwrap-in-tests](#allow-unwrap-in-tests) | `false` | +| [allow-dbg-in-tests](#allow-dbg-in-tests) | `false` | +| [allow-print-in-tests](#allow-print-in-tests) | `false` | +| [large-error-threshold](#large-error-threshold) | `128` | +| [ignore-interior-mutability](#ignore-interior-mutability) | `["bytes::Bytes"]` | +| [allow-mixed-uninlined-format-args](#allow-mixed-uninlined-format-args) | `true` | +| [suppress-restriction-lint-in-const](#suppress-restriction-lint-in-const) | `false` | +| [missing-docs-in-crate-items](#missing-docs-in-crate-items) | `false` | +| [future-size-threshold](#future-size-threshold) | `16384` | +| [unnecessary-box-size](#unnecessary-box-size) | `128` | +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) -### arithmetic-side-effects-allowed +The following list shows each configuration option, along with a description, its default value, an example +and lints affected. + +--- + +## `arithmetic-side-effects-allowed` Suppress checking of the passed type names in all types of operations. If a specific operation is desired, consider using `arithmetic_side_effects_allowed_binary` or `arithmetic_side_effects_allowed_unary` instead. @@ -74,10 +158,12 @@ A type, say `SomeType`, listed in this configuration has the same behavior of **Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet`) -* [arithmetic_side_effects](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects) +--- +**Affected lints:** +* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects) -### arithmetic-side-effects-allowed-binary +## `arithmetic-side-effects-allowed-binary` Suppress checking of the passed type pair names in binary operations like addition or multiplication. @@ -95,10 +181,12 @@ arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", **Default Value:** `[]` (`Vec<[String; 2]>`) -* [arithmetic_side_effects](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects) +--- +**Affected lints:** +* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects) -### arithmetic-side-effects-allowed-unary +## `arithmetic-side-effects-allowed-unary` Suppress checking of the passed type names in unary operations like "negation" (`-`). #### Example @@ -109,100 +197,208 @@ arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"] **Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet`) -* [arithmetic_side_effects](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects) +--- +**Affected lints:** +* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects) -### avoid-breaking-exported-api +## `avoid-breaking-exported-api` Suppress lints whenever the suggested change would cause breakage for other crates. **Default Value:** `true` (`bool`) -* [enum_variant_names](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names) -* [large_types_passed_by_value](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value) -* [trivially_copy_pass_by_ref](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref) -* [unnecessary_wraps](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps) -* [unused_self](https://rust-lang.github.io/rust-clippy/master/index.html#unused_self) -* [upper_case_acronyms](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms) -* [wrong_self_convention](https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention) -* [box_collection](https://rust-lang.github.io/rust-clippy/master/index.html#box_collection) -* [redundant_allocation](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation) -* [rc_buffer](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer) -* [vec_box](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box) -* [option_option](https://rust-lang.github.io/rust-clippy/master/index.html#option_option) -* [linkedlist](https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist) -* [rc_mutex](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex) -* [unnecessary_box_returns](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns) - - -### msrv +--- +**Affected lints:** +* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names) +* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value) +* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref) +* [`unnecessary_wraps`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps) +* [`unused_self`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_self) +* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms) +* [`wrong_self_convention`](https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention) +* [`box_collection`](https://rust-lang.github.io/rust-clippy/master/index.html#box_collection) +* [`redundant_allocation`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation) +* [`rc_buffer`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer) +* [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box) +* [`option_option`](https://rust-lang.github.io/rust-clippy/master/index.html#option_option) +* [`linkedlist`](https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist) +* [`rc_mutex`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex) +* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns) +<<<<<<< HEAD +<<<<<<< HEAD +* [`single_call_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn) +======= +>>>>>>> b7a605471 (Refresh Lint Configuration's looks) +======= +* [`single_call_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn) +>>>>>>> 2cd4a9182 (Ignore functions annotated with `#[test]`) + + +## `msrv` The minimum rust version that the project supports **Default Value:** `None` (`Option`) -* [manual_split_once](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once) -* [manual_str_repeat](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat) -* [cloned_instead_of_copied](https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied) -* [redundant_field_names](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names) -* [redundant_static_lifetimes](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes) -* [filter_map_next](https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next) -* [checked_conversions](https://rust-lang.github.io/rust-clippy/master/index.html#checked_conversions) -* [manual_range_contains](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains) -* [use_self](https://rust-lang.github.io/rust-clippy/master/index.html#use_self) -* [mem_replace_with_default](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default) -* [manual_non_exhaustive](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive) -* [option_as_ref_deref](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref) -* [map_unwrap_or](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or) -* [match_like_matches_macro](https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro) -* [manual_strip](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip) -* [missing_const_for_fn](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn) -* [unnested_or_patterns](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns) -* [from_over_into](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into) -* [ptr_as_ptr](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr) -* [if_then_some_else_none](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none) -* [approx_constant](https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant) -* [deprecated_cfg_attr](https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr) -* [index_refutable_slice](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice) -* [map_clone](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone) -* [borrow_as_ptr](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr) -* [manual_bits](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits) -* [err_expect](https://rust-lang.github.io/rust-clippy/master/index.html#err_expect) -* [cast_abs_to_unsigned](https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned) -* [uninlined_format_args](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args) -* [manual_clamp](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp) -* [manual_let_else](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else) -* [unchecked_duration_subtraction](https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction) -* [collapsible_str_replace](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace) -* [seek_from_current](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current) -* [seek_rewind](https://rust-lang.github.io/rust-clippy/master/index.html#seek_rewind) -* [unnecessary_lazy_evaluations](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations) -* [transmute_ptr_to_ref](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref) -* [almost_complete_range](https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range) -* [needless_borrow](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow) -* [derivable_impls](https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls) -* [manual_is_ascii_check](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check) -* [manual_rem_euclid](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid) -* [manual_retain](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain) - - -### cognitive-complexity-threshold +--- +**Affected lints:** +* [`manual_split_once`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once) +* [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat) +* [`cloned_instead_of_copied`](https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied) +* [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names) +<<<<<<< HEAD +<<<<<<< HEAD +* [`option_map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or) +======= +>>>>>>> b7a605471 (Refresh Lint Configuration's looks) +======= +* [`option_map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or) +>>>>>>> bb42b1808 (ran `cargo collect-metadata`) +* [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes) +* [`filter_map_next`](https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next) +* [`checked_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#checked_conversions) +* [`manual_range_contains`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains) +* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self) +* [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default) +* [`manual_non_exhaustive`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive) +* [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref) +* [`map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or) +* [`match_like_matches_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro) +* [`manual_strip`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip) +* [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn) +* [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns) +* [`from_over_into`](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into) +* [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr) +* [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none) +* [`approx_constant`](https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant) +* [`deprecated_cfg_attr`](https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr) +* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice) +* [`map_clone`](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone) +* [`borrow_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr) +* [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits) +* [`err_expect`](https://rust-lang.github.io/rust-clippy/master/index.html#err_expect) +* [`cast_abs_to_unsigned`](https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned) +* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args) +* [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp) +* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else) +* [`unchecked_duration_subtraction`](https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction) +* [`collapsible_str_replace`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace) +* [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current) +* [`seek_rewind`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_rewind) +* [`unnecessary_lazy_evaluations`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations) +* [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref) +* [`almost_complete_range`](https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range) +* [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow) +* [`derivable_impls`](https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls) +* [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check) +* [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid) +* [`manual_retain`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain) +<<<<<<< HEAD +<<<<<<< HEAD +* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds) +* [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions) +<<<<<<< HEAD +<<<<<<< HEAD +* [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold) +======= +>>>>>>> b7a605471 (Refresh Lint Configuration's looks) +======= +* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds) +>>>>>>> 75f9fbc93 (update lint configuration) +======= +>>>>>>> 826edd75e (heavily refactor) +======= +* [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold) +>>>>>>> cb5d7e344 (address comments) + + +## `cognitive-complexity-threshold` The maximum cognitive complexity a function can have **Default Value:** `25` (`u64`) -* [cognitive_complexity](https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity) +--- +**Affected lints:** +* [`cognitive_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity) + + +<<<<<<< HEAD +<<<<<<< HEAD +## `excessive-nesting-threshold` +The maximum amount of nesting a block can reside in + +**Default Value:** `0` (`u64`) +======= +## `excessive-nesting-threshold` +The maximum amount of nesting a block can reside in +<<<<<<< HEAD +**Default Value:** `10` (`u64`) +>>>>>>> 88143ac29 (decided against reinventing the wheel) +======= +**Default Value:** `0` (`u64`) +>>>>>>> 725399a17 (move to `complexity` but don't lint by default) -### disallowed-names +--- +**Affected lints:** +* [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting) + + +<<<<<<< HEAD +======= +>>>>>>> b7a605471 (Refresh Lint Configuration's looks) +======= +>>>>>>> 88143ac29 (decided against reinventing the wheel) +## `disallowed-names` The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value -`".."` can be used as part of the list to indicate, that the configured values should be appended to the +`".."` can be used as part of the list to indicate that the configured values should be appended to the default configuration of Clippy. By default, any configuration will replace the default value. **Default Value:** `["foo", "baz", "quux"]` (`Vec`) -* [disallowed_names](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names) +--- +**Affected lints:** +* [`disallowed_names`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names) + + +<<<<<<< HEAD +## `semicolon-inside-block-ignore-singleline` +======= +### semicolon-inside-block-ignore-singleline +>>>>>>> e4f5d83fa (Fixed formatting.) +Whether to lint only if it's multiline. + +**Default Value:** `false` (`bool`) + +<<<<<<< HEAD +--- +**Affected lints:** +* [`semicolon_inside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block) + + +## `semicolon-outside-block-ignore-multiline` +======= +* [semicolon_inside_block](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block) + + +### semicolon-outside-block-ignore-multiline +>>>>>>> e4f5d83fa (Fixed formatting.) +Whether to lint only if it's singleline. + +**Default Value:** `false` (`bool`) + +<<<<<<< HEAD +--- +**Affected lints:** +* [`semicolon_outside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block) + + +## `doc-valid-idents` +======= +* [semicolon_outside_block](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block) ### doc-valid-idents +>>>>>>> e4f5d83fa (Fixed formatting.) The list of words this lint should not consider as identifiers needing ticks. The value `".."` can be used as part of the list to indicate, that the configured values should be appended to the default configuration of Clippy. By default, any configuration will replace the default value. For example: @@ -211,207 +407,295 @@ default configuration of Clippy. By default, any configuration will replace the Default list: -**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` (`Vec`) +**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` (`Vec`) -* [doc_markdown](https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown) +--- +**Affected lints:** +* [`doc_markdown`](https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown) -### too-many-arguments-threshold +## `too-many-arguments-threshold` The maximum number of argument a function or method can have **Default Value:** `7` (`u64`) -* [too_many_arguments](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments) +--- +**Affected lints:** +* [`too_many_arguments`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments) -### type-complexity-threshold +## `type-complexity-threshold` The maximum complexity a type can have **Default Value:** `250` (`u64`) -* [type_complexity](https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity) +--- +**Affected lints:** +* [`type_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity) -### single-char-binding-names-threshold +## `single-char-binding-names-threshold` The maximum number of single char bindings a scope may have **Default Value:** `4` (`u64`) -* [many_single_char_names](https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names) +--- +**Affected lints:** +* [`many_single_char_names`](https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names) -### too-large-for-stack +## `too-large-for-stack` The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap **Default Value:** `200` (`u64`) -* [boxed_local](https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local) -* [useless_vec](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec) +--- +**Affected lints:** +* [`boxed_local`](https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local) +* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec) -### enum-variant-name-threshold +## `enum-variant-name-threshold` The minimum number of enum variants for the lints about variant names to trigger **Default Value:** `3` (`u64`) -* [enum_variant_names](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names) +--- +**Affected lints:** +* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names) -### enum-variant-size-threshold +## `enum-variant-size-threshold` The maximum size of an enum's variant to avoid box suggestion **Default Value:** `200` (`u64`) -* [large_enum_variant](https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant) +--- +**Affected lints:** +* [`large_enum_variant`](https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant) -### verbose-bit-mask-threshold +## `verbose-bit-mask-threshold` The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros' **Default Value:** `1` (`u64`) -* [verbose_bit_mask](https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask) +--- +**Affected lints:** +* [`verbose_bit_mask`](https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask) -### literal-representation-threshold +## `literal-representation-threshold` The lower bound for linting decimal literals **Default Value:** `16384` (`u64`) -* [decimal_literal_representation](https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation) +--- +**Affected lints:** +* [`decimal_literal_representation`](https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation) -### trivial-copy-size-limit +## `trivial-copy-size-limit` The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by reference. **Default Value:** `None` (`Option`) -* [trivially_copy_pass_by_ref](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref) +--- +**Affected lints:** +* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref) -### pass-by-value-size-limit +## `pass-by-value-size-limit` The minimum size (in bytes) to consider a type for passing by reference instead of by value. **Default Value:** `256` (`u64`) -* [large_types_passed_by_value](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value) +--- +**Affected lints:** +* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value) -### too-many-lines-threshold +## `too-many-lines-threshold` The maximum number of lines a function or method can have **Default Value:** `100` (`u64`) -* [too_many_lines](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines) +--- +**Affected lints:** +* [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines) -### array-size-threshold +## `array-size-threshold` The maximum allowed size for arrays on the stack **Default Value:** `512000` (`u64`) -* [large_stack_arrays](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays) -* [large_const_arrays](https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays) +--- +**Affected lints:** +* [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays) +* [`large_const_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays) +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +## `stack-size-threshold` +======= +### stack-size-threshold +>>>>>>> 7312a93a0 (new lint: `large_stack_frames`) +======= +## `stack-size-threshold` +>>>>>>> c8c7a3c79 (fix rebase weirdness) +The maximum allowed stack size for functions in bytes + +**Default Value:** `512000` (`u64`) + +<<<<<<< HEAD +<<<<<<< HEAD +--- +**Affected lints:** +* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames) + + +======= +>>>>>>> b7a605471 (Refresh Lint Configuration's looks) +## `vec-box-size-threshold` +======= +* [large_stack_frames](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames) +======= +--- +**Affected lints:** +* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames) +>>>>>>> 6ad7c6f4e (update lint_configuration.md) + + +<<<<<<< HEAD ### vec-box-size-threshold +>>>>>>> 7312a93a0 (new lint: `large_stack_frames`) +======= +## `vec-box-size-threshold` +>>>>>>> c8c7a3c79 (fix rebase weirdness) The size of the boxed type in bytes, where boxing in a `Vec` is allowed **Default Value:** `4096` (`u64`) -* [vec_box](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box) +--- +**Affected lints:** +* [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box) -### max-trait-bounds +## `max-trait-bounds` The maximum number of bounds a trait can have to be linted **Default Value:** `3` (`u64`) -* [type_repetition_in_bounds](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds) +--- +**Affected lints:** +* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds) -### max-struct-bools +## `max-struct-bools` The maximum number of bool fields a struct can have **Default Value:** `3` (`u64`) -* [struct_excessive_bools](https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools) +--- +**Affected lints:** +* [`struct_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools) -### max-fn-params-bools +## `max-fn-params-bools` The maximum number of bool parameters a function can have **Default Value:** `3` (`u64`) -* [fn_params_excessive_bools](https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools) +--- +**Affected lints:** +* [`fn_params_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools) -### warn-on-all-wildcard-imports +## `warn-on-all-wildcard-imports` Whether to allow certain wildcard imports (prelude, super in tests). **Default Value:** `false` (`bool`) -* [wildcard_imports](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports) +--- +**Affected lints:** +* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports) -### disallowed-macros +## `disallowed-macros` The list of disallowed macros, written as fully qualified paths. **Default Value:** `[]` (`Vec`) -* [disallowed_macros](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_macros) +--- +**Affected lints:** +* [`disallowed_macros`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_macros) -### disallowed-methods +## `disallowed-methods` The list of disallowed methods, written as fully qualified paths. **Default Value:** `[]` (`Vec`) -* [disallowed_methods](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods) +--- +**Affected lints:** +* [`disallowed_methods`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods) -### disallowed-types +## `disallowed-types` The list of disallowed types, written as fully qualified paths. **Default Value:** `[]` (`Vec`) -* [disallowed_types](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types) +--- +**Affected lints:** +* [`disallowed_types`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types) -### unreadable-literal-lint-fractions +## `unreadable-literal-lint-fractions` Should the fraction of a decimal be linted to include separators. **Default Value:** `true` (`bool`) -* [unreadable_literal](https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal) +--- +**Affected lints:** +* [`unreadable_literal`](https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal) -### upper-case-acronyms-aggressive +## `upper-case-acronyms-aggressive` Enables verbose mode. Triggers if there is more than one uppercase char next to each other **Default Value:** `false` (`bool`) -* [upper_case_acronyms](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms) +--- +**Affected lints:** +* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms) -### matches-for-let-else +## `matches-for-let-else` Whether the matches should be considered by the lint, and whether there should be filtering for common types. **Default Value:** `WellKnownTypes` (`crate::manual_let_else::MatchLintBehaviour`) -* [manual_let_else](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else) +--- +**Affected lints:** +* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else) -### cargo-ignore-publish +## `cargo-ignore-publish` For internal testing only, ignores the current `publish` settings in the Cargo manifest. **Default Value:** `false` (`bool`) -* [_cargo_common_metadata](https://rust-lang.github.io/rust-clippy/master/index.html#_cargo_common_metadata) +--- +**Affected lints:** +* [`_cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#_cargo_common_metadata) -### standard-macro-braces +## `standard-macro-braces` Enforce the named macros always use the braces specified. A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro @@ -420,119 +704,147 @@ could be used with a full path two `MacroMatcher`s have to be added one with the **Default Value:** `[]` (`Vec`) -* [nonstandard_macro_braces](https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces) +--- +**Affected lints:** +* [`nonstandard_macro_braces`](https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces) -### enforced-import-renames +## `enforced-import-renames` The list of imports to always rename, a fully qualified path followed by the rename. **Default Value:** `[]` (`Vec`) -* [missing_enforced_import_renames](https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames) +--- +**Affected lints:** +* [`missing_enforced_import_renames`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames) -### allowed-scripts +## `allowed-scripts` The list of unicode scripts allowed to be used in the scope. **Default Value:** `["Latin"]` (`Vec`) -* [disallowed_script_idents](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents) +--- +**Affected lints:** +* [`disallowed_script_idents`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents) -### enable-raw-pointer-heuristic-for-send +## `enable-raw-pointer-heuristic-for-send` Whether to apply the raw pointer heuristic to determine if a type is `Send`. **Default Value:** `true` (`bool`) -* [non_send_fields_in_send_ty](https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty) +--- +**Affected lints:** +* [`non_send_fields_in_send_ty`](https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty) -### max-suggested-slice-pattern-length +## `max-suggested-slice-pattern-length` When Clippy suggests using a slice pattern, this is the maximum number of elements allowed in the slice pattern that is suggested. If more elements are necessary, the lint is suppressed. For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements. **Default Value:** `3` (`u64`) -* [index_refutable_slice](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice) +--- +**Affected lints:** +* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice) -### await-holding-invalid-types +## `await-holding-invalid-types` **Default Value:** `[]` (`Vec`) -* [await_holding_invalid_type](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type) +--- +**Affected lints:** +* [`await_holding_invalid_type`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type) -### max-include-file-size +## `max-include-file-size` The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes **Default Value:** `1000000` (`u64`) -* [large_include_file](https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file) +--- +**Affected lints:** +* [`large_include_file`](https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file) -### allow-expect-in-tests +## `allow-expect-in-tests` Whether `expect` should be allowed in test functions or `#[cfg(test)]` **Default Value:** `false` (`bool`) -* [expect_used](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used) +--- +**Affected lints:** +* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used) -### allow-unwrap-in-tests +## `allow-unwrap-in-tests` Whether `unwrap` should be allowed in test functions or `#[cfg(test)]` **Default Value:** `false` (`bool`) -* [unwrap_used](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used) +--- +**Affected lints:** +* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used) -### allow-dbg-in-tests +## `allow-dbg-in-tests` Whether `dbg!` should be allowed in test functions or `#[cfg(test)]` **Default Value:** `false` (`bool`) -* [dbg_macro](https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro) +--- +**Affected lints:** +* [`dbg_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro) -### allow-print-in-tests +## `allow-print-in-tests` Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]` **Default Value:** `false` (`bool`) -* [print_stdout](https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout) -* [print_stderr](https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr) +--- +**Affected lints:** +* [`print_stdout`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout) +* [`print_stderr`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr) -### large-error-threshold +## `large-error-threshold` The maximum size of the `Err`-variant in a `Result` returned from a function **Default Value:** `128` (`u64`) -* [result_large_err](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err) +--- +**Affected lints:** +* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err) -### ignore-interior-mutability +## `ignore-interior-mutability` A list of paths to types that should be treated like `Arc`, i.e. ignored but for the generic parameters for determining interior mutability **Default Value:** `["bytes::Bytes"]` (`Vec`) -* [mutable_key_type](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type) -* [ifs_same_cond](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond) +--- +**Affected lints:** +* [`mutable_key_type`](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type) +* [`ifs_same_cond`](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond) -### allow-mixed-uninlined-format-args +## `allow-mixed-uninlined-format-args` Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)` **Default Value:** `true` (`bool`) -* [uninlined_format_args](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args) +--- +**Affected lints:** +* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args) -### suppress-restriction-lint-in-const +## `suppress-restriction-lint-in-const` Whether to suppress a restriction lint in constant code. In same cases the restructured operation might not be unavoidable, as the suggested counterparts are unavailable in constant code. This @@ -541,24 +853,191 @@ if no suggestion can be made. **Default Value:** `false` (`bool`) -* [indexing_slicing](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing) +--- +**Affected lints:** +* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing) -### missing-docs-in-crate-items +## `missing-docs-in-crate-items` Whether to **only** check for missing documentation in items visible within the current crate. For example, `pub(crate)` items. **Default Value:** `false` (`bool`) -* [missing_docs_in_private_items](https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items) +--- +**Affected lints:** +* [`missing_docs_in_private_items`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items) -### future-size-threshold +## `future-size-threshold` The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint **Default Value:** `16384` (`u64`) -* [large_futures](https://rust-lang.github.io/rust-clippy/master/index.html#large_futures) +--- +**Affected lints:** +* [`large_futures`](https://rust-lang.github.io/rust-clippy/master/index.html#large_futures) + + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) +### unnecessary-box-size +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +## `unnecessary-box-size` +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 203e87518 (`cargo collect-metadata`) +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +The byte size a `T` in `Box` can have, below which it triggers the `clippy::unnecessary_box` lint +======= +### unnecessary-box-size +The byte size a `T` in `Box` can have, below which it triggers the `clippy::unnecessary_box` lint + +**Default Value:** `128` (`u64`) + +* [unnecessary_box_returns](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns) + + +>>>>>>> e4f5d83fa (Fixed formatting.) + +**Default Value:** `128` (`u64`) + +--- +**Affected lints:** +* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns) +<<<<<<< HEAD +<<<<<<< HEAD + +======= +>>>>>>> b7a605471 (Refresh Lint Configuration's looks) +======= +>>>>>>> 203e87518 (`cargo collect-metadata`) +## `allow-private-module-inception` +Whether to allow module inception if it's not public. + +**Default Value:** `false` (`bool`) + +--- +**Affected lints:** +* [`module_inception`](https://rust-lang.github.io/rust-clippy/master/index.html#module_inception) + + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) +======= +## `allowed-idents-below-min-chars` +Allowed names below the minimum allowed characters. The value `".."` can be used as part of +the list to indicate, that the configured values should be appended to the default +configuration of Clippy. By default, any configuration will replace the default value. +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) + +**Default Value:** `{"j", "z", "i", "y", "n", "x", "w"}` (`rustc_data_structures::fx::FxHashSet`) + +--- +**Affected lints:** +* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars) + + +## `min-ident-chars-threshold` +Minimum chars an ident can have, anything below or equal to this will be linted. + +**Default Value:** `1` (`u64`) + +--- +**Affected lints:** +* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars) + + +<<<<<<< HEAD +<<<<<<< HEAD +## `accept-comment-above-statement` +Whether to accept a safety comment to be placed above the statement containing the `unsafe` block +======= +## `accept-comment-above-statement` +<<<<<<< HEAD +Whether to accept a safety comment to be placed above the statement containing the `usafe` block +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= +Whether to accept a safety comment to be placed above the statement containing the `unsafe` block +>>>>>>> e2e6a0244 (Addressing reviewer comments) + +**Default Value:** `false` (`bool`) + +--- +**Affected lints:** +* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks) + + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) +## `accept-comment-above-attributes` +Whether to accept a safety comment to be placed above the attributes for the `unsafe` block + +**Default Value:** `false` (`bool`) + +--- +**Affected lints:** +* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks) + + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +## `allow-one-hash-in-raw-strings` +======= +## `allow-one-hash-in-raw-string` +>>>>>>> cb52d19ce (don't lint `needless_raw_string_hashes` when it's unnecessary) +======= +## `allow-one-hash-in-raw-strings` +>>>>>>> 8cb6c8699 (change category and refactor) +Whether to allow `r#""#` when `r""` can be used + +**Default Value:** `false` (`bool`) + +--- +**Affected lints:** +* [`unnecessary_raw_string_hashes`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_raw_string_hashes) + + +<<<<<<< HEAD +## `allow-private-module-inception` +Whether to allow module inception if it's not public. + +**Default Value:** `false` (`bool`) +--- +**Affected lints:** +* [`module_inception`](https://rust-lang.github.io/rust-clippy/master/index.html#module_inception) + + +======= +>>>>>>> 243943ff5 (make it work for locals as well) +======= +>>>>>>> 203e87518 (`cargo collect-metadata`) +======= +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) +======= +>>>>>>> cb52d19ce (don't lint `needless_raw_string_hashes` when it's unnecessary) diff --git a/book/src/usage.md b/book/src/usage.md index 32084a9199b7..36448e4cccfa 100644 --- a/book/src/usage.md +++ b/book/src/usage.md @@ -111,7 +111,8 @@ fn main() { ### Automatically applying Clippy suggestions -Clippy can automatically apply some lint suggestions, just like the compiler. +Clippy can automatically apply some lint suggestions, just like the compiler. Note that `--fix` implies +`--all-targets`, so it can fix as much code as it can. ```terminal cargo clippy --fix diff --git a/clippy_dev/src/bless.rs b/clippy_dev/src/bless.rs deleted file mode 100644 index 92b2771f3fe7..000000000000 --- a/clippy_dev/src/bless.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! `bless` updates the reference files in the repo with changed output files -//! from the last test run. - -use crate::cargo_clippy_path; -use std::ffi::OsStr; -use std::fs; -use std::path::{Path, PathBuf}; -use std::sync::LazyLock; -use walkdir::{DirEntry, WalkDir}; - -static CLIPPY_BUILD_TIME: LazyLock> = - LazyLock::new(|| cargo_clippy_path().metadata().ok()?.modified().ok()); - -/// # Panics -/// -/// Panics if the path to a test file is broken -pub fn bless(ignore_timestamp: bool) { - let extensions = ["stdout", "stderr", "fixed"].map(OsStr::new); - - WalkDir::new(build_dir()) - .into_iter() - .map(Result::unwrap) - .filter(|entry| entry.path().extension().map_or(false, |ext| extensions.contains(&ext))) - .for_each(|entry| update_reference_file(&entry, ignore_timestamp)); -} - -fn update_reference_file(test_output_entry: &DirEntry, ignore_timestamp: bool) { - let test_output_path = test_output_entry.path(); - - let reference_file_name = test_output_entry.file_name().to_str().unwrap().replace(".stage-id", ""); - let reference_file_path = Path::new("tests") - .join(test_output_path.strip_prefix(build_dir()).unwrap()) - .with_file_name(reference_file_name); - - // If the test output was not updated since the last clippy build, it may be outdated - if !ignore_timestamp && !updated_since_clippy_build(test_output_entry).unwrap_or(true) { - return; - } - - let test_output_file = fs::read(test_output_path).expect("Unable to read test output file"); - let reference_file = fs::read(&reference_file_path).unwrap_or_default(); - - if test_output_file != reference_file { - // If a test run caused an output file to change, update the reference file - println!("updating {}", reference_file_path.display()); - fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file"); - } -} - -fn updated_since_clippy_build(entry: &DirEntry) -> Option { - let clippy_build_time = (*CLIPPY_BUILD_TIME)?; - let modified = entry.metadata().ok()?.modified().ok()?; - Some(modified >= clippy_build_time) -} - -fn build_dir() -> PathBuf { - let mut path = std::env::current_exe().unwrap(); - path.set_file_name("test"); - path -} diff --git a/clippy_dev/src/dogfood.rs b/clippy_dev/src/dogfood.rs index b69e9f649ec7..a0d57f5ab483 100644 --- a/clippy_dev/src/dogfood.rs +++ b/clippy_dev/src/dogfood.rs @@ -1,4 +1,4 @@ -use crate::clippy_project_root; +use crate::{clippy_project_root, exit_if_err}; use std::process::Command; /// # Panics @@ -10,7 +10,7 @@ pub fn dogfood(fix: bool, allow_dirty: bool, allow_staged: bool) { cmd.current_dir(clippy_project_root()) .args(["test", "--test", "dogfood"]) .args(["--features", "internal"]) - .args(["--", "dogfood_clippy"]); + .args(["--", "dogfood_clippy", "--nocapture"]); let mut dogfood_args = Vec::new(); if fix { @@ -27,7 +27,5 @@ pub fn dogfood(fix: bool, allow_dirty: bool, allow_staged: bool) { cmd.env("__CLIPPY_DOGFOOD_ARGS", dogfood_args.join(" ")); - let output = cmd.output().expect("failed to run command"); - - println!("{}", String::from_utf8_lossy(&output.stdout)); + exit_if_err(cmd.status()); } diff --git a/clippy_dev/src/fmt.rs b/clippy_dev/src/fmt.rs index 256231441817..ee559d45dd16 100644 --- a/clippy_dev/src/fmt.rs +++ b/clippy_dev/src/fmt.rs @@ -35,6 +35,7 @@ struct FmtContext { } // the "main" function of cargo dev fmt +#[allow(clippy::missing_panics_doc)] pub fn run(check: bool, verbose: bool) { fn try_run(context: &FmtContext) -> Result { let mut success = true; diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs index 3a8b070d7351..caebd501f7fe 100644 --- a/clippy_dev/src/lib.rs +++ b/clippy_dev/src/lib.rs @@ -10,9 +10,10 @@ extern crate rustc_driver; extern crate rustc_lexer; +use std::io; use std::path::PathBuf; +use std::process::{self, ExitStatus}; -pub mod bless; pub mod dogfood; pub mod fmt; pub mod lint; @@ -27,6 +28,10 @@ static CARGO_CLIPPY_EXE: &str = "cargo-clippy"; static CARGO_CLIPPY_EXE: &str = "cargo-clippy.exe"; /// Returns the path to the `cargo-clippy` binary +/// +/// # Panics +/// +/// Panics if the path of current executable could not be retrieved. #[must_use] pub fn cargo_clippy_path() -> PathBuf { let mut path = std::env::current_exe().expect("failed to get current executable name"); @@ -58,3 +63,19 @@ pub fn clippy_project_root() -> PathBuf { } panic!("error: Can't determine root of project. Please run inside a Clippy working dir."); } + +<<<<<<< HEAD +/// # Panics +/// Panics if given command result was failed. +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +pub fn exit_if_err(status: io::Result) { + match status.expect("failed to run command").code() { + Some(0) => {}, + Some(n) => process::exit(n), + None => { + eprintln!("Killed by signal"); + process::exit(1); + }, + } +} diff --git a/clippy_dev/src/lint.rs b/clippy_dev/src/lint.rs index aafd0f71a59b..a19be1bca6c3 100644 --- a/clippy_dev/src/lint.rs +++ b/clippy_dev/src/lint.rs @@ -1,17 +1,6 @@ -use crate::cargo_clippy_path; -use std::process::{self, Command, ExitStatus}; -use std::{fs, io}; - -fn exit_if_err(status: io::Result) { - match status.expect("failed to run command").code() { - Some(0) => {}, - Some(n) => process::exit(n), - None => { - eprintln!("Killed by signal"); - process::exit(1); - }, - } -} +use crate::{cargo_clippy_path, exit_if_err}; +use std::fs; +use std::process::{self, Command}; pub fn run<'a>(path: &str, args: impl Iterator) { let is_file = match fs::metadata(path) { diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs index e2457e5a8a5e..20f2eba915b4 100644 --- a/clippy_dev/src/main.rs +++ b/clippy_dev/src/main.rs @@ -3,15 +3,16 @@ #![warn(rust_2018_idioms, unused_lifetimes)] use clap::{Arg, ArgAction, ArgMatches, Command}; -use clippy_dev::{bless, dogfood, fmt, lint, new_lint, serve, setup, update_lints}; +use clippy_dev::{dogfood, fmt, lint, new_lint, serve, setup, update_lints}; use indoc::indoc; +use std::convert::Infallible; fn main() { let matches = get_clap_config(); match matches.subcommand() { - Some(("bless", matches)) => { - bless::bless(matches.get_flag("ignore-timestamp")); + Some(("bless", _)) => { + eprintln!("use `cargo bless` to automatically replace `.stderr` and `.fixed` files as tests are being run"); }, Some(("dogfood", matches)) => { dogfood::dogfood( @@ -34,7 +35,7 @@ fn main() { }, Some(("new_lint", matches)) => { match new_lint::create( - matches.get_one::("pass"), + matches.get_one::("pass").unwrap(), matches.get_one::("name"), matches.get_one::("category").map(String::as_str), matches.get_one::("type").map(String::as_str), @@ -175,12 +176,31 @@ fn get_clap_config() -> ArgMatches { .help("Specify whether the lint runs during the early or late pass") .value_parser(["early", "late"]) .conflicts_with("type") - .required_unless_present("type"), + .default_value("late"), Arg::new("name") .short('n') .long("name") .help("Name of the new lint in snake case, ex: fn_too_long") - .required(true), + .required(true) +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + .value_parser(|name: &str| Ok::<_, Infallible>(name.replace('-', "_"))), +======= + .value_parser(|name: &str| { + if name.contains('-') { + Err("Lint name cannot contain `-`, use `_` instead.") + } else { + Ok(name.to_owned()) + } + }), +>>>>>>> a3438da42 (error out if lint name contains dash) +======= + .value_parser(|name: &str| Ok::<_, Infallible>(name.replace("-", "_"))), +>>>>>>> 95b5a7bbe (replace `-` instead of erroring out) +======= + .value_parser(|name: &str| Ok::<_, Infallible>(name.replace('-', "_"))), +>>>>>>> c70f2a2e5 (apply suggestion) Arg::new("category") .short('c') .long("category") diff --git a/clippy_dev/src/new_lint.rs b/clippy_dev/src/new_lint.rs index 13a277034278..f11aa547bd73 100644 --- a/clippy_dev/src/new_lint.rs +++ b/clippy_dev/src/new_lint.rs @@ -36,8 +36,9 @@ impl Context for io::Result { /// # Errors /// /// This function errors out if the files couldn't be created or written to. +#[allow(clippy::missing_panics_doc)] pub fn create( - pass: Option<&String>, + pass: &String, lint_name: Option<&String>, category: Option<&str>, mut ty: Option<&str>, @@ -49,7 +50,7 @@ pub fn create( } let lint = LintData { - pass: pass.map_or("", String::as_str), + pass, name: lint_name.expect("`name` argument is validated by clap"), category: category.expect("`category` argument is validated by clap"), ty, @@ -63,6 +64,14 @@ pub fn create( add_lint(&lint, msrv).context("Unable to add lint to clippy_lints/src/lib.rs")?; } + if pass == "early" { + println!( + "\n\ + NOTE: Use a late pass unless you need something specific from\ + an early pass, as they lack many features and utilities" + ); + } + Ok(()) } @@ -87,7 +96,7 @@ fn create_test(lint: &LintData<'_>) -> io::Result<()> { path.push("src"); fs::create_dir(&path)?; - let header = format!("// compile-flags: --crate-name={lint_name}"); + let header = format!("//@compile-flags: --crate-name={lint_name}"); write_file(path.join("main.rs"), get_test_file_contents(lint_name, Some(&header)))?; Ok(()) diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs index 95222a9acdfc..7213c9dfede9 100644 --- a/clippy_dev/src/update_lints.rs +++ b/clippy_dev/src/update_lints.rs @@ -36,60 +36,6 @@ pub enum UpdateMode { pub fn update(update_mode: UpdateMode) { let (lints, deprecated_lints, renamed_lints) = gather_all(); generate_lint_files(update_mode, &lints, &deprecated_lints, &renamed_lints); - remove_old_files(update_mode); -} - -/// Remove files no longer needed after -/// that may be reintroduced unintentionally -/// -/// FIXME: This is a temporary measure that should be removed when there are no more PRs that -/// include the stray files -fn remove_old_files(update_mode: UpdateMode) { - let mut failed = false; - let mut remove_file = |path: &Path| match update_mode { - UpdateMode::Check => { - if path.exists() { - failed = true; - println!("unexpected file: {}", path.display()); - } - }, - UpdateMode::Change => { - if fs::remove_file(path).is_ok() { - println!("removed file: {}", path.display()); - } - }, - }; - - let files = [ - "clippy_lints/src/lib.register_all.rs", - "clippy_lints/src/lib.register_cargo.rs", - "clippy_lints/src/lib.register_complexity.rs", - "clippy_lints/src/lib.register_correctness.rs", - "clippy_lints/src/lib.register_internal.rs", - "clippy_lints/src/lib.register_lints.rs", - "clippy_lints/src/lib.register_nursery.rs", - "clippy_lints/src/lib.register_pedantic.rs", - "clippy_lints/src/lib.register_perf.rs", - "clippy_lints/src/lib.register_restriction.rs", - "clippy_lints/src/lib.register_style.rs", - "clippy_lints/src/lib.register_suspicious.rs", - "src/docs.rs", - ]; - - for file in files { - remove_file(Path::new(file)); - } - - if let Ok(docs_dir) = fs::read_dir("src/docs") { - for doc_file in docs_dir { - let path = doc_file.unwrap().path(); - remove_file(&path); - } - } - - if failed { - exit_with_failure(); - } } fn generate_lint_files( @@ -741,7 +687,7 @@ fn gen_deprecated_lints_test(lints: &[DeprecatedLint]) -> String { fn gen_renamed_lints_test(lints: &[RenamedLint]) -> String { let mut seen_lints = HashSet::new(); let mut res: String = GENERATED_FILE_COMMENT.into(); - res.push_str("// run-rustfix\n\n"); + res.push_str("//@run-rustfix\n\n"); for lint in lints { if seen_lints.insert(&lint.new_name) { writeln!(res, "#![allow({})]", lint.new_name).unwrap(); diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index 5c6040f63f50..f13fa94a0d66 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,6 +1,10 @@ [package] name = "clippy_lints" -version = "0.1.70" +<<<<<<< HEAD +version = "0.1.73" +======= +version = "0.1.71" +>>>>>>> e4f5d83fa (Fixed formatting.) description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" @@ -17,23 +21,37 @@ if_chain = "1.0" itertools = "0.10.1" pulldown-cmark = { version = "0.9", default-features = false } quine-mc_cluskey = "0.2" -regex-syntax = "0.6" +regex-syntax = "0.7" serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", optional = true } tempfile = { version = "3.3.0", optional = true } +<<<<<<< HEAD +<<<<<<< HEAD toml = "0.5" +======= +toml = "0.7.3" +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> e6dc0efc0 (Merge commit '30448e8cf98d4754350db0c959644564f317bc0f' into clippyup) +======= +regex = { version = "1.5", optional = true } +>>>>>>> cb3ecf7b7 (Merge commit '37f4c1725d3fd7e9c3ffd8783246bc5589debc53' into clippyup) +======= +toml = "0.7.3" +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= +regex = { version = "1.5", optional = true } +>>>>>>> 7ac15f900 (Add lint to check lint formulation messages) unicode-normalization = "0.1" unicode-script = { version = "0.5", default-features = false } semver = "1.0" rustc-semver = "1.1" -# NOTE: cargo requires serde feat in its url dep -# see -url = { version = "2.2", features = ["serde"] } +url = "2.2" [features] deny-warnings = ["clippy_utils/deny-warnings"] # build clippy with internal lints enabled, off by default -internal = ["clippy_utils/internal", "serde_json", "tempfile"] +internal = ["clippy_utils/internal", "serde_json", "tempfile", "regex"] [package.metadata.rust-analyzer] # This crate uses #[feature(rustc_private)] diff --git a/clippy_lints/src/allow_attributes.rs b/clippy_lints/src/allow_attributes.rs index b984132acf5b..10fc1414d1ae 100644 --- a/clippy_lints/src/allow_attributes.rs +++ b/clippy_lints/src/allow_attributes.rs @@ -1,8 +1,22 @@ +<<<<<<< HEAD +<<<<<<< HEAD +use ast::{AttrStyle, Attribute}; +<<<<<<< HEAD +======= use ast::AttrStyle; +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= +use ast::{AttrStyle, Attribute}; +>>>>>>> 05bfcbd91 (remove tuple) +use clippy_utils::{diagnostics::span_lint_and_sugg, is_from_proc_macro}; +======= use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_from_proc_macro; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) use rustc_ast as ast; use rustc_errors::Applicability; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { @@ -39,7 +53,7 @@ declare_clippy_lint! { /// a.len() /// } /// ``` - #[clippy::version = "1.69.0"] + #[clippy::version = "1.70.0"] pub ALLOW_ATTRIBUTES, restriction, "`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings." @@ -49,12 +63,22 @@ declare_lint_pass!(AllowAttribute => [ALLOW_ATTRIBUTES]); impl LateLintPass<'_> for AllowAttribute { // Separate each crate's features. - fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) { + fn check_attribute<'cx>(&mut self, cx: &LateContext<'cx>, attr: &'cx Attribute) { if_chain! { + if !in_external_macro(cx.sess(), attr.span); if cx.tcx.features().lint_reasons; if let AttrStyle::Outer = attr.style; if let Some(ident) = attr.ident(); if ident.name == rustc_span::symbol::sym::allow; +<<<<<<< HEAD +<<<<<<< HEAD + if !is_from_proc_macro(cx, &attr); +======= + if !is_from_proc_macro(cx, &(attr, cx)); +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= + if !is_from_proc_macro(cx, &attr); +>>>>>>> 05bfcbd91 (remove tuple) then { span_lint_and_sugg( cx, diff --git a/clippy_lints/src/arc_with_non_send_sync.rs b/clippy_lints/src/arc_with_non_send_sync.rs new file mode 100644 index 000000000000..432fce805505 --- /dev/null +++ b/clippy_lints/src/arc_with_non_send_sync.rs @@ -0,0 +1,175 @@ +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::last_path_segment; +use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; +use rustc_hir::{Expr, ExprKind}; +<<<<<<< HEAD +use rustc_lint::LateContext; +use rustc_lint::LateLintPass; +<<<<<<< HEAD +<<<<<<< HEAD +======= +use rustc_lint::{LateContext, LateLintPass}; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_middle::ty; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 339cd14f2 (Adds new lint `arc_with_non_send_or_sync`) +======= +use rustc_middle::ty; +>>>>>>> 2f5d1c748 (Adding extra check to ignore generic args.) +======= +======= +use rustc_middle::ty::print::with_forced_trimmed_paths; +>>>>>>> 4939a716e (arc_with_non_send_sync: reword and move to suspicious) +use rustc_middle::ty::GenericArgKind; +>>>>>>> 75c339cd0 ([`arc_with_non_send_sync`]: look for nested type parameters) +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::symbol::sym; + +declare_clippy_lint! { + /// ### What it does. + /// This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`. + /// + /// ### Why is this bad? + /// `Arc` is only `Send`/`Sync` when `T` is [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-Send-for-Arc%3CT%3E), + /// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc` + /// +<<<<<<< HEAD +<<<<<<< HEAD + /// ### Example + /// ```rust + /// # use std::cell::RefCell; + /// # use std::sync::Arc; +======= + /// ### Example. + /// ```rust + /// use std::cell::RefCell; + /// use std::sync::Arc; +>>>>>>> 339cd14f2 (Adds new lint `arc_with_non_send_or_sync`) +======= + /// ### Example + /// ```rust + /// # use std::cell::RefCell; + /// # use std::sync::Arc; +>>>>>>> 8330887e1 (Updating documentation and lint formatting.) + /// + /// fn main() { + /// // This is fine, as `i32` implements `Send` and `Sync`. + /// let a = Arc::new(42); + /// + /// // `RefCell` is `!Sync`, so either the `Arc` should be replaced with an `Rc` + /// // or the `RefCell` replaced with something like a `RwLock` + /// let b = Arc::new(RefCell::new(42)); + /// } + /// ``` +<<<<<<< HEAD +<<<<<<< HEAD +======= + /// ``` +>>>>>>> 339cd14f2 (Adds new lint `arc_with_non_send_or_sync`) +======= +>>>>>>> 8330887e1 (Updating documentation and lint formatting.) + #[clippy::version = "1.72.0"] + pub ARC_WITH_NON_SEND_SYNC, + suspicious, + "using `Arc` with a type that does not implement `Send` or `Sync`" +} +declare_lint_pass!(ArcWithNonSendSync => [ARC_WITH_NON_SEND_SYNC]); + +impl LateLintPass<'_> for ArcWithNonSendSync { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + let ty = cx.typeck_results().expr_ty(expr); +<<<<<<< HEAD + if_chain! { + if is_type_diagnostic_item(cx, ty, sym::Arc); + if let ExprKind::Call(func, [arg]) = expr.kind; + if let ExprKind::Path(func_path) = func.kind; + if last_path_segment(&func_path).ident.name == sym::new; + if let arg_ty = cx.typeck_results().expr_ty(arg); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if !matches!(arg_ty.kind(), ty::Param(_)); +======= +>>>>>>> 339cd14f2 (Adds new lint `arc_with_non_send_or_sync`) +======= + if match arg_ty.kind() { + ty::Param(_) => false, + _ => true, + }; +>>>>>>> 2f5d1c748 (Adding extra check to ignore generic args.) +======= + if !matches!(arg_ty.kind(), ty::Param(_)); +>>>>>>> 20548eba6 (Swapping to matches macro.) +======= +======= + if is_type_diagnostic_item(cx, ty, sym::Arc) + && let ExprKind::Call(func, [arg]) = expr.kind + && let ExprKind::Path(func_path) = func.kind + && last_path_segment(&func_path).ident.name == sym::new + && let arg_ty = cx.typeck_results().expr_ty(arg) +>>>>>>> 4939a716e (arc_with_non_send_sync: reword and move to suspicious) + // make sure that the type is not and does not contain any type parameters + && arg_ty.walk().all(|arg| { + !matches!(arg.unpack(), GenericArgKind::Type(ty) if matches!(ty.kind(), ty::Param(_))) +<<<<<<< HEAD + }); +>>>>>>> 75c339cd0 ([`arc_with_non_send_sync`]: look for nested type parameters) + if !cx.tcx + .lang_items() + .sync_trait() + .map_or(false, |id| implements_trait(cx, arg_ty, id, &[])) || + !cx.tcx + .get_diagnostic_item(sym::Send) + .map_or(false, |id| implements_trait(cx, arg_ty, id, &[])); + + then { + span_lint_and_help( + cx, + ARC_WITH_NON_SEND_SYNC, + expr.span, + "usage of `Arc` where `T` is not `Send` or `Sync`", + None, + "consider using `Rc` instead or wrapping `T` in a std::sync type like \ +<<<<<<< HEAD +<<<<<<< HEAD + `Mutex`", +======= + Mutex", +>>>>>>> 339cd14f2 (Adds new lint `arc_with_non_send_or_sync`) +======= + `Mutex`", +>>>>>>> 8330887e1 (Updating documentation and lint formatting.) + ); + } +======= + }) + && let Some(send) = cx.tcx.get_diagnostic_item(sym::Send) + && let Some(sync) = cx.tcx.lang_items().sync_trait() + && let [is_send, is_sync] = [send, sync].map(|id| implements_trait(cx, arg_ty, id, &[])) + && !(is_send && is_sync) + { + span_lint_and_then( + cx, + ARC_WITH_NON_SEND_SYNC, + expr.span, + "usage of an `Arc` that is not `Send` or `Sync`", + |diag| with_forced_trimmed_paths!({ + if !is_send { + diag.note(format!("the trait `Send` is not implemented for `{arg_ty}`")); + } + if !is_sync { + diag.note(format!("the trait `Sync` is not implemented for `{arg_ty}`")); + } + + diag.note(format!("required for `{ty}` to implement `Send` and `Sync`")); + + diag.help("consider using an `Rc` instead or wrapping the inner type with a `Mutex`"); + } + )); +>>>>>>> 4939a716e (arc_with_non_send_sync: reword and move to suspicious) + } + } +} diff --git a/clippy_lints/src/as_conversions.rs b/clippy_lints/src/as_conversions.rs index c7a76e5f9077..b9dda49ca412 100644 --- a/clippy_lints/src/as_conversions.rs +++ b/clippy_lints/src/as_conversions.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_help; -use rustc_ast::ast::{Expr, ExprKind}; -use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; +use clippy_utils::is_from_proc_macro; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -45,9 +46,9 @@ declare_clippy_lint! { declare_lint_pass!(AsConversions => [AS_CONVERSIONS]); -impl EarlyLintPass for AsConversions { - fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { - if in_external_macro(cx.sess(), expr.span) { +impl<'tcx> LateLintPass<'tcx> for AsConversions { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { + if in_external_macro(cx.sess(), expr.span) || is_from_proc_macro(cx, expr) { return; } diff --git a/clippy_lints/src/assertions_on_constants.rs b/clippy_lints/src/assertions_on_constants.rs index a36df55d0bda..a8dc0cb3b581 100644 --- a/clippy_lints/src/assertions_on_constants.rs +++ b/clippy_lints/src/assertions_on_constants.rs @@ -38,7 +38,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants { _ => return, }; let Some((condition, panic_expn)) = find_assert_args(cx, e, macro_call.expn) else { return }; - let Some((Constant::Bool(val), _)) = constant(cx, cx.typeck_results(), condition) else { return }; + let Some(Constant::Bool(val)) = constant(cx, cx.typeck_results(), condition) else { return }; if val { span_lint_and_help( cx, diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 751c262673b1..a7a1f401aba0 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -1,6 +1,7 @@ //! checks for attributes use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::is_from_proc_macro; use clippy_utils::macros::{is_panic, macro_backtrace}; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments}; @@ -176,6 +177,52 @@ declare_clippy_lint! { "empty line after outer attribute" } +declare_clippy_lint! { + /// ### What it does + /// Checks for empty lines after documenation comments. + /// + /// ### Why is this bad? + /// The documentation comment was most likely meant to be an inner attribute or regular comment. + /// If it was intended to be a documentation comment, then the empty line should be removed to + /// be more idiomatic. + /// + /// ### Known problems + /// Only detects empty lines immediately following the documentation. If the doc comment is followed + /// by an attribute and then an empty line, this lint will not trigger. Use `empty_line_after_outer_attr` + /// in combination with this lint to detect both cases. + /// + /// Does not detect empty lines after doc attributes (e.g. `#[doc = ""]`). + /// + /// ### Example + /// ```rust + /// /// Some doc comment with a blank line after it. + /// + /// fn not_quite_good_code() { } + /// ``` + /// + /// Use instead: + /// ```rust + /// /// Good (no blank line) + /// fn this_is_fine() { } + /// ``` + /// + /// ```rust + /// // Good (convert to a regular comment) + /// + /// fn this_is_fine_too() { } + /// ``` + /// + /// ```rust + /// //! Good (convert to a comment on an inner attribute) + /// + /// fn this_is_fine_as_well() { } + /// ``` + #[clippy::version = "1.70.0"] + pub EMPTY_LINE_AFTER_DOC_COMMENTS, + nursery, + "empty line after documentation comments" +} + declare_clippy_lint! { /// ### What it does /// Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category. @@ -292,6 +339,65 @@ declare_clippy_lint! { "ensures that all `allow` and `expect` attributes have a reason" } +declare_clippy_lint! { + /// ### What it does + /// Checks for `any` and `all` combinators in `cfg` with only one condition. + /// + /// ### Why is this bad? + /// If there is only one condition, no need to wrap it into `any` or `all` combinators. + /// + /// ### Example + /// ```rust + /// #[cfg(any(unix))] + /// pub struct Bar; + /// ``` + /// + /// Use instead: + /// ```rust + /// #[cfg(unix)] + /// pub struct Bar; + /// ``` + #[clippy::version = "1.71.0"] + pub NON_MINIMAL_CFG, + style, + "ensure that all `cfg(any())` and `cfg(all())` have more than one condition" +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> ad76687b2 (add checking for cfg(features = ...)) +declare_clippy_lint! { + /// ### What it does + /// Checks for `#[cfg(features = "...")]` and suggests to replace it with + /// `#[cfg(feature = "...")]`. + /// + /// ### Why is this bad? + /// Misspelling `feature` as `features` can be sometimes hard to spot. It + /// may cause conditional compilation not work quitely. + /// + /// ### Example + /// ```rust + /// #[cfg(features = "some-feature")] + /// fn conditional() { } + /// ``` + /// + /// Use instead: + /// ```rust + /// #[cfg(feature = "some-feature")] + /// fn conditional() { } + /// ``` + #[clippy::version = "1.69.0"] + pub MAYBE_MISUSED_CFG, + suspicious, + "prevent from misusing the wrong attr name" +} + +<<<<<<< HEAD +======= +>>>>>>> ab66a8681 (Add new `UNIQUE_CFG_CONDITION` lint) +======= +>>>>>>> ad76687b2 (add checking for cfg(features = ...)) declare_lint_pass!(Attributes => [ ALLOW_ATTRIBUTES_WITHOUT_REASON, INLINE_ALWAYS, @@ -470,7 +576,15 @@ fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMe } } -fn check_lint_reason(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem], attr: &'_ Attribute) { +<<<<<<< HEAD +<<<<<<< HEAD +fn check_lint_reason<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMetaItem], attr: &'cx Attribute) { +======= +fn check_lint_reason(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem], attr: &Attribute) { +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= +fn check_lint_reason<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMetaItem], attr: &'cx Attribute) { +>>>>>>> 05bfcbd91 (remove tuple) // Check for the feature if !cx.tcx.features().lint_reasons { return; @@ -485,7 +599,15 @@ fn check_lint_reason(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem } // Check if the attribute is in an external macro and therefore out of the developer's control - if in_external_macro(cx.sess(), attr.span) { +<<<<<<< HEAD +<<<<<<< HEAD + if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, &attr) { +======= + if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, &(attr, cx)) { +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= + if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, &attr) { +>>>>>>> 05bfcbd91 (remove tuple) return; } @@ -604,6 +726,26 @@ impl_lint_pass!(EarlyAttributes => [ DEPRECATED_CFG_ATTR, MISMATCHED_TARGET_OS, EMPTY_LINE_AFTER_OUTER_ATTR, + EMPTY_LINE_AFTER_DOC_COMMENTS, +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= + NON_MINIMAL_CFG, +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +======= + MAYBE_MISUSED_CFG, +>>>>>>> cb3ecf7b7 (Merge commit '37f4c1725d3fd7e9c3ffd8783246bc5589debc53' into clippyup) +======= + NON_MINIMAL_CFG, +>>>>>>> ab66a8681 (Add new `UNIQUE_CFG_CONDITION` lint) +======= + MAYBE_MISUSED_CFG, +>>>>>>> ad76687b2 (add checking for cfg(features = ...)) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) ]); impl EarlyLintPass for EarlyAttributes { @@ -614,15 +756,30 @@ impl EarlyLintPass for EarlyAttributes { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) { check_deprecated_cfg_attr(cx, attr, &self.msrv); check_mismatched_target_os(cx, attr); + check_minimal_cfg_condition(cx, attr); +<<<<<<< HEAD +<<<<<<< HEAD + check_misused_cfg(cx, attr); +======= +>>>>>>> ab66a8681 (Add new `UNIQUE_CFG_CONDITION` lint) +======= + check_misused_cfg(cx, attr); +>>>>>>> ad76687b2 (add checking for cfg(features = ...)) } extract_msrv_attr!(EarlyContext); } +/// Check for empty lines after outer attributes. +/// +/// Attributes and documenation comments are both considered outer attributes +/// by the AST. However, the average user likely considers them to be different. +/// Checking for empty lines after each of these attributes is split into two different +/// lints but can share the same logic. fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::Item) { let mut iter = item.attrs.iter().peekable(); while let Some(attr) = iter.next() { - if matches!(attr.kind, AttrKind::Normal(..)) + if (matches!(attr.kind, AttrKind::Normal(..)) || matches!(attr.kind, AttrKind::DocComment(..))) && attr.style == AttrStyle::Outer && is_present_in_source(cx, attr.span) { @@ -639,13 +796,20 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::It let lines = without_block_comments(lines); if lines.iter().filter(|l| l.trim().is_empty()).count() > 2 { - span_lint( - cx, - EMPTY_LINE_AFTER_OUTER_ATTR, - begin_of_attr_to_item, - "found an empty line after an outer attribute. \ - Perhaps you forgot to add a `!` to make it an inner attribute?", - ); + let (lint_msg, lint_type) = match attr.kind { + AttrKind::DocComment(..) => ( + "found an empty line after a doc comment. \ + Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?", + EMPTY_LINE_AFTER_DOC_COMMENTS, + ), + AttrKind::Normal(..) => ( + "found an empty line after an outer attribute. \ + Perhaps you forgot to add a `!` to make it an inner attribute?", + EMPTY_LINE_AFTER_OUTER_ATTR, + ), + }; + + span_lint(cx, lint_type, begin_of_attr_to_item, lint_msg); } } } @@ -690,6 +854,118 @@ fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &Msr } } +fn check_nested_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) { +<<<<<<< HEAD +<<<<<<< HEAD + for item in items { +======= + for item in items.iter() { +>>>>>>> ab66a8681 (Add new `UNIQUE_CFG_CONDITION` lint) +======= + for item in items { +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + if let NestedMetaItem::MetaItem(meta) = item { + if !meta.has_name(sym::any) && !meta.has_name(sym::all) { + continue; + } + if let MetaItemKind::List(list) = &meta.kind { + check_nested_cfg(cx, list); + if list.len() == 1 { + span_lint_and_then( + cx, + NON_MINIMAL_CFG, + meta.span, + "unneeded sub `cfg` when there is only one condition", + |diag| { + if let Some(snippet) = snippet_opt(cx, list[0].span()) { + diag.span_suggestion(meta.span, "try", snippet, Applicability::MaybeIncorrect); + } + }, + ); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> dbc76a766 (Add check for empty cfg `all` condition) + } else if list.is_empty() && meta.has_name(sym::all) { + span_lint_and_then( + cx, + NON_MINIMAL_CFG, + meta.span, + "unneeded sub `cfg` when there is no condition", + |_| {}, + ); +<<<<<<< HEAD +======= +>>>>>>> ab66a8681 (Add new `UNIQUE_CFG_CONDITION` lint) +======= +>>>>>>> dbc76a766 (Add check for empty cfg `all` condition) + } + } + } + } +} + +<<<<<<< HEAD +<<<<<<< HEAD +fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) { + for item in items { +======= +fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) { +<<<<<<< HEAD + for item in items.iter() { +>>>>>>> ad76687b2 (add checking for cfg(features = ...)) +======= + for item in items { +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + if let NestedMetaItem::MetaItem(meta) = item { + if meta.has_name(sym!(features)) && let Some(val) = meta.value_str() { + span_lint_and_sugg( + cx, + MAYBE_MISUSED_CFG, + meta.span, + "feature may misspelled as features", + "use", + format!("feature = \"{val}\""), + Applicability::MaybeIncorrect, + ); + } + if let MetaItemKind::List(list) = &meta.kind { + check_nested_misused_cfg(cx, list); + } + } + } +} + +<<<<<<< HEAD +======= +>>>>>>> ab66a8681 (Add new `UNIQUE_CFG_CONDITION` lint) +======= +>>>>>>> ad76687b2 (add checking for cfg(features = ...)) +fn check_minimal_cfg_condition(cx: &EarlyContext<'_>, attr: &Attribute) { + if attr.has_name(sym::cfg) && + let Some(items) = attr.meta_item_list() + { + check_nested_cfg(cx, &items); + } +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> ad76687b2 (add checking for cfg(features = ...)) +fn check_misused_cfg(cx: &EarlyContext<'_>, attr: &Attribute) { + if attr.has_name(sym::cfg) && + let Some(items) = attr.meta_item_list() + { + check_nested_misused_cfg(cx, &items); + } +} + +<<<<<<< HEAD +======= +>>>>>>> ab66a8681 (Add new `UNIQUE_CFG_CONDITION` lint) +======= +>>>>>>> ad76687b2 (add checking for cfg(features = ...)) fn check_mismatched_target_os(cx: &EarlyContext<'_>, attr: &Attribute) { fn find_os(name: &str) -> Option<&'static str> { UNIX_SYSTEMS diff --git a/clippy_lints/src/blocks_in_if_conditions.rs b/clippy_lints/src/blocks_in_if_conditions.rs index 569bf27c3e71..1593d7b0fb38 100644 --- a/clippy_lints/src/blocks_in_if_conditions.rs +++ b/clippy_lints/src/blocks_in_if_conditions.rs @@ -1,9 +1,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; -use clippy_utils::get_parent_expr; -use clippy_utils::higher; use clippy_utils::source::snippet_block_with_applicability; use clippy_utils::ty::implements_trait; use clippy_utils::visitors::{for_each_expr, Descend}; +use clippy_utils::{get_parent_expr, higher}; use core::ops::ControlFlow; use if_chain::if_chain; use rustc_errors::Applicability; diff --git a/clippy_lints/src/bool_assert_comparison.rs b/clippy_lints/src/bool_assert_comparison.rs index 1d9096ea64d1..e8775b081444 100644 --- a/clippy_lints/src/bool_assert_comparison.rs +++ b/clippy_lints/src/bool_assert_comparison.rs @@ -41,7 +41,7 @@ fn extract_bool_lit(e: &Expr<'_>) -> Option { }) = e.kind && !e.span.from_expansion() { - Some(b) + Some(*b) } else { None } @@ -61,7 +61,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) - ) }) .map_or(false, |assoc_item| { - let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, [])); + let proj = Ty::new_projection(cx.tcx,assoc_item.def_id, cx.tcx.mk_substs_trait(ty, [])); let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj); nty.is_bool() diff --git a/clippy_lints/src/bool_to_int_with_if.rs b/clippy_lints/src/bool_to_int_with_if.rs index bdb3a0116027..1828dd651527 100644 --- a/clippy_lints/src/bool_to_int_with_if.rs +++ b/clippy_lints/src/bool_to_int_with_if.rs @@ -4,7 +4,9 @@ use rustc_hir::{Block, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use clippy_utils::{diagnostics::span_lint_and_then, in_constant, is_else_clause, is_integer_literal, sugg::Sugg}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::sugg::Sugg; +use clippy_utils::{in_constant, is_else_clause, is_integer_literal}; use rustc_errors::Applicability; declare_clippy_lint! { diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index 455f0df7cd0a..62d1507500ce 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -88,7 +88,34 @@ impl<'tcx> LateLintPass<'tcx> for NonminimalBool { NonminimalBoolVisitor { cx }.visit_body(body); } } +<<<<<<< HEAD +<<<<<<< HEAD +======= +fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { + cx.tcx + .lang_items() + .not_trait() + .filter(|trait_id| implements_trait(cx, ty, *trait_id, &[])) + .and_then(|trait_id| { + cx.tcx.associated_items(trait_id).find_by_name_and_kind( + cx.tcx, + Ident::from_str("Output"), + ty::AssocKind::Type, + trait_id, + ) + }) + .map_or(false, |assoc_item| { + let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, [])); + let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj); + + nty.is_bool() + }) +} + +>>>>>>> d3534a652 (fix issues 10836) +======= +>>>>>>> e4927f98f (change booleans file and update tests) struct NonminimalBoolVisitor<'a, 'tcx> { cx: &'a LateContext<'tcx>, } @@ -441,7 +468,7 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> { diag.span_suggestions( e.span, "try", - suggestions.into_iter(), + suggestions, // nonminimal_bool can produce minimal but // not human readable expressions (#3141) Applicability::Unspecified, @@ -473,6 +500,24 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> { self.bool_expr(e); }, ExprKind::Unary(UnOp::Not, inner) => { +<<<<<<< HEAD +<<<<<<< HEAD + if let ExprKind::Unary(UnOp::Not, ex) = inner.kind && + !self.cx.typeck_results().node_types()[ex.hir_id].is_bool() { + return; +======= + if let ExprKind::Unary(UnOp::Not, ex) = inner.kind { + let ty = self.cx.typeck_results().expr_ty(ex); + if is_impl_not_trait_with_bool_out(self.cx, ty) { + return; + } +>>>>>>> d3534a652 (fix issues 10836) +======= + if let ExprKind::Unary(UnOp::Not, ex) = inner.kind && + !self.cx.typeck_results().node_types()[ex.hir_id].is_bool() { + return; +>>>>>>> e4927f98f (change booleans file and update tests) + } if self.cx.typeck_results().node_types()[inner.hir_id].is_bool() { self.bool_expr(e); } diff --git a/clippy_lints/src/borrow_deref_ref.rs b/clippy_lints/src/borrow_deref_ref.rs index c4520d003928..514133da4460 100644 --- a/clippy_lints/src/borrow_deref_ref.rs +++ b/clippy_lints/src/borrow_deref_ref.rs @@ -1,8 +1,9 @@ use crate::reference::DEREF_ADDROF; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::is_from_proc_macro; use clippy_utils::source::snippet_opt; use clippy_utils::ty::implements_trait; -use clippy_utils::{get_parent_expr, is_lint_allowed}; +use clippy_utils::{get_parent_expr, is_from_proc_macro, is_lint_allowed}; use rustc_errors::Applicability; use rustc_hir::{ExprKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; @@ -47,8 +48,8 @@ declare_clippy_lint! { declare_lint_pass!(BorrowDerefRef => [BORROW_DEREF_REF]); -impl LateLintPass<'_> for BorrowDerefRef { - fn check_expr(&mut self, cx: &LateContext<'_>, e: &rustc_hir::Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &rustc_hir::Expr<'tcx>) { if_chain! { if !e.span.from_expansion(); if let ExprKind::AddrOf(_, Mutability::Not, addrof_target) = e.kind; @@ -58,6 +59,7 @@ impl LateLintPass<'_> for BorrowDerefRef { if !matches!(deref_target.kind, ExprKind::Unary(UnOp::Deref, ..) ); let ref_ty = cx.typeck_results().expr_ty(deref_target); if let ty::Ref(_, inner_ty, Mutability::Not) = ref_ty.kind(); + if !is_from_proc_macro(cx, e); then{ if let Some(parent_expr) = get_parent_expr(cx, e){ diff --git a/clippy_lints/src/box_default.rs b/clippy_lints/src/box_default.rs index dfa949d1af2f..fa9c525fc08d 100644 --- a/clippy_lints/src/box_default.rs +++ b/clippy_lints/src/box_default.rs @@ -1,14 +1,14 @@ -use clippy_utils::{ - diagnostics::span_lint_and_sugg, get_parent_node, is_default_equivalent, macros::macro_backtrace, match_path, - path_def_id, paths, ty::expr_sig, -}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::macros::macro_backtrace; +use clippy_utils::ty::expr_sig; +use clippy_utils::{get_parent_node, is_default_equivalent, match_path, path_def_id, paths}; use rustc_errors::Applicability; -use rustc_hir::{ - intravisit::{walk_ty, Visitor}, - Block, Expr, ExprKind, Local, Node, QPath, TyKind, -}; +use rustc_hir::intravisit::{walk_ty, Visitor}; +use rustc_hir::{Block, Expr, ExprKind, Local, Node, QPath, TyKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::{lint::in_external_macro, ty::print::with_forced_trimmed_paths}; +use rustc_middle::lint::in_external_macro; +use rustc_middle::ty::print::with_forced_trimmed_paths; +use rustc_middle::ty::IsSuggestable; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; @@ -49,7 +49,6 @@ impl LateLintPass<'_> for BoxDefault { && path_def_id(cx, ty).map_or(false, |id| Some(id) == cx.tcx.lang_items().owned_box()) && is_default_equivalent(cx, arg) { - let arg_ty = cx.typeck_results().expr_ty(arg); span_lint_and_sugg( cx, BOX_DEFAULT, @@ -58,8 +57,10 @@ impl LateLintPass<'_> for BoxDefault { "try", if is_plain_default(arg_path) || given_type(cx, expr) { "Box::default()".into() - } else { + } else if let Some(arg_ty) = cx.typeck_results().expr_ty(arg).make_suggestable(cx.tcx, true) { with_forced_trimmed_paths!(format!("Box::<{arg_ty}>::default()")) + } else { + return }, Applicability::MachineApplicable ); diff --git a/clippy_lints/src/casts/as_ptr_cast_mut.rs b/clippy_lints/src/casts/as_ptr_cast_mut.rs index 1633ffd589c3..e3d1f7df2945 100644 --- a/clippy_lints/src/casts/as_ptr_cast_mut.rs +++ b/clippy_lints/src/casts/as_ptr_cast_mut.rs @@ -3,10 +3,8 @@ use clippy_utils::source::snippet_opt; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; -use rustc_middle::{ - mir::Mutability, - ty::{self, Ty, TypeAndMut}, -}; +use rustc_middle::mir::Mutability; +use rustc_middle::ty::{self, Ty, TypeAndMut}; use super::AS_PTR_CAST_MUT; diff --git a/clippy_lints/src/casts/borrow_as_ptr.rs b/clippy_lints/src/casts/borrow_as_ptr.rs index 294d22d34de9..0c56ea3e5b89 100644 --- a/clippy_lints/src/casts/borrow_as_ptr.rs +++ b/clippy_lints/src/casts/borrow_as_ptr.rs @@ -4,6 +4,7 @@ use clippy_utils::source::snippet_with_context; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Ty, TyKind}; use rustc_lint::LateContext; +use rustc_middle::ty::adjustment::Adjust; use super::BORROW_AS_PTR; @@ -23,6 +24,25 @@ pub(super) fn check<'tcx>( }; let mut app = Applicability::MachineApplicable; let snip = snippet_with_context(cx, e.span, cast_expr.span.ctxt(), "..", &mut app).0; + // Fix #9884 +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 72aa18079 (use rustc's criteria for a temporary) + if !e.is_place_expr(|base| { + cx.typeck_results() + .adjustments() + .get(base.hir_id) + .is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_)))) + }) { +<<<<<<< HEAD +======= + if for_each_unconsumed_temporary(cx, expr, |_| ControlFlow::Break(true)).is_break() { +>>>>>>> d2725402a ([`borrow_as_ptr`]: Ignore temporaries) +======= +>>>>>>> 72aa18079 (use rustc's criteria for a temporary) + return; + } span_lint_and_sugg( cx, diff --git a/clippy_lints/src/casts/cast_nan_to_int.rs b/clippy_lints/src/casts/cast_nan_to_int.rs index 322dc41b3a19..da756129db3a 100644 --- a/clippy_lints/src/casts/cast_nan_to_int.rs +++ b/clippy_lints/src/casts/cast_nan_to_int.rs @@ -21,8 +21,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, fn is_known_nan(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { match constant(cx, cx.typeck_results(), e) { - Some((Constant::F64(n), _)) => n.is_nan(), - Some((Constant::F32(n), _)) => n.is_nan(), + Some(Constant::F64(n)) => n.is_nan(), + Some(Constant::F32(n)) => n.is_nan(), _ => false, } } diff --git a/clippy_lints/src/casts/cast_possible_truncation.rs b/clippy_lints/src/casts/cast_possible_truncation.rs index 95c2ecbf791b..84b99ad5c243 100644 --- a/clippy_lints/src/casts/cast_possible_truncation.rs +++ b/clippy_lints/src/casts/cast_possible_truncation.rs @@ -15,7 +15,7 @@ use rustc_target::abi::IntegerType; use super::{utils, CAST_ENUM_TRUNCATION, CAST_POSSIBLE_TRUNCATION}; fn constant_int(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { - if let Some((Constant::Int(c), _)) = constant(cx, cx.typeck_results(), expr) { + if let Some(Constant::Int(c)) = constant(cx, cx.typeck_results(), expr) { Some(c) } else { None diff --git a/clippy_lints/src/casts/cast_possible_wrap.rs b/clippy_lints/src/casts/cast_possible_wrap.rs index 28ecdea7ea06..4ebe121053c9 100644 --- a/clippy_lints/src/casts/cast_possible_wrap.rs +++ b/clippy_lints/src/casts/cast_possible_wrap.rs @@ -1,41 +1,117 @@ +<<<<<<< HEAD +<<<<<<< HEAD +======= use clippy_utils::diagnostics::span_lint; -use clippy_utils::ty::is_isize_or_usize; +>>>>>>> 6681914b5 (make cast_possible_wrap not lint on conversions for sizes that cannot wrap, and make it work correctly for 16 bit {u,i}size) +======= +>>>>>>> 7cd0ec58a (add more info link) use rustc_hir::Expr; -use rustc_lint::LateContext; +use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty::Ty; use super::{utils, CAST_POSSIBLE_WRAP}; +// this should be kept in sync with the allowed bit widths of `usize` and `isize` +const ALLOWED_POINTER_SIZES: [u64; 3] = [16, 32, 64]; + +// whether the lint should be emitted, and the required pointer size, if it matters +<<<<<<< HEAD +<<<<<<< HEAD +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +======= +>>>>>>> 6681914b5 (make cast_possible_wrap not lint on conversions for sizes that cannot wrap, and make it work correctly for 16 bit {u,i}size) +======= +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +>>>>>>> 7cd0ec58a (add more info link) +enum EmitState { + NoLint, + LintAlways, + LintOnPtrSize(u64), +} + pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { if !(cast_from.is_integral() && cast_to.is_integral()) { return; } - let arch_64_suffix = " on targets with 64-bit wide pointers"; - let arch_32_suffix = " on targets with 32-bit wide pointers"; - let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed(); + // emit a lint if a cast is: + // 1. unsigned to signed + // and + // 2. either: +<<<<<<< HEAD + // +======= +>>>>>>> 6681914b5 (make cast_possible_wrap not lint on conversions for sizes that cannot wrap, and make it work correctly for 16 bit {u,i}size) + // 2a. between two types of constant size that are always the same size + // 2b. between one target-dependent size and one constant size integer, + // and the constant integer is in the allowed set of target dependent sizes + // (the ptr size could be chosen to be the same as the constant size) + + if cast_from.is_signed() || !cast_to.is_signed() { + return; + } + let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx); let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx); - let (should_lint, suffix) = match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) { - (true, true) | (false, false) => (to_nbits == from_nbits && cast_unsigned_to_signed, ""), - (true, false) => (to_nbits <= 32 && cast_unsigned_to_signed, arch_32_suffix), - (false, true) => ( - cast_unsigned_to_signed, - if from_nbits == 64 { - arch_64_suffix + let should_lint = match (cast_from.is_ptr_sized_integral(), cast_to.is_ptr_sized_integral()) { + (true, true) => { + // casts between two ptr sized integers are trivially always the same size + // so do not depend on any specific pointer size to be the same + EmitState::LintAlways + }, + (true, false) => { + // the first type is `usize` and the second is a constant sized signed integer + if ALLOWED_POINTER_SIZES.contains(&to_nbits) { + EmitState::LintOnPtrSize(to_nbits) + } else { + EmitState::NoLint + } + }, + (false, true) => { + // the first type is a constant sized unsigned integer, and the second is `isize` + if ALLOWED_POINTER_SIZES.contains(&from_nbits) { + EmitState::LintOnPtrSize(from_nbits) + } else { + EmitState::NoLint + } + }, + (false, false) => { + // the types are both a constant known size + // and do not depend on any specific pointer size to be the same + if from_nbits == to_nbits { + EmitState::LintAlways } else { - arch_32_suffix - }, + EmitState::NoLint + } + }, + }; + + let message = match should_lint { + EmitState::NoLint => return, + EmitState::LintAlways => format!("casting `{cast_from}` to `{cast_to}` may wrap around the value"), + EmitState::LintOnPtrSize(ptr_size) => format!( + "casting `{cast_from}` to `{cast_to}` may wrap around the value on targets with {ptr_size}-bit wide pointers", ), }; - if should_lint { - span_lint( - cx, - CAST_POSSIBLE_WRAP, - expr.span, - &format!("casting `{cast_from}` to `{cast_to}` may wrap around the value{suffix}",), - ); - } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 7cd0ec58a (add more info link) + cx.struct_span_lint(CAST_POSSIBLE_WRAP, expr.span, message, |diag| { + if let EmitState::LintOnPtrSize(16) = should_lint { + diag + .note("`usize` and `isize` may be as small as 16 bits on some platforms") + .note("for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types") + } else { + diag + } + }); +<<<<<<< HEAD +======= + span_lint(cx, CAST_POSSIBLE_WRAP, expr.span, message.as_str()); +>>>>>>> 6681914b5 (make cast_possible_wrap not lint on conversions for sizes that cannot wrap, and make it work correctly for 16 bit {u,i}size) +======= +>>>>>>> 7cd0ec58a (add more info link) } diff --git a/clippy_lints/src/casts/cast_ref_to_mut.rs b/clippy_lints/src/casts/cast_ref_to_mut.rs deleted file mode 100644 index 15f2f81f4079..000000000000 --- a/clippy_lints/src/casts/cast_ref_to_mut.rs +++ /dev/null @@ -1,26 +0,0 @@ -use clippy_utils::diagnostics::span_lint; -use if_chain::if_chain; -use rustc_hir::{Expr, ExprKind, MutTy, Mutability, TyKind, UnOp}; -use rustc_lint::LateContext; -use rustc_middle::ty; - -use super::CAST_REF_TO_MUT; - -pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { - if_chain! { - if let ExprKind::Unary(UnOp::Deref, e) = &expr.kind; - if let ExprKind::Cast(e, t) = &e.kind; - if let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind; - if let ExprKind::Cast(e, t) = &e.kind; - if let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind; - if let ty::Ref(..) = cx.typeck_results().node_type(e.hir_id).kind(); - then { - span_lint( - cx, - CAST_REF_TO_MUT, - expr.span, - "casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell`", - ); - } - } -} diff --git a/clippy_lints/src/casts/cast_sign_loss.rs b/clippy_lints/src/casts/cast_sign_loss.rs index a20a97d4e56d..a83dfd94dc22 100644 --- a/clippy_lints/src/casts/cast_sign_loss.rs +++ b/clippy_lints/src/casts/cast_sign_loss.rs @@ -29,7 +29,7 @@ fn should_lint(cx: &LateContext<'_>, cast_op: &Expr<'_>, cast_from: Ty<'_>, cast // Don't lint for positive constants. let const_val = constant(cx, cx.typeck_results(), cast_op); if_chain! { - if let Some((Constant::Int(n), _)) = const_val; + if let Some(Constant::Int(n)) = const_val; if let ty::Int(ity) = *cast_from.kind(); if sext(cx.tcx, n, ity) >= 0; then { diff --git a/clippy_lints/src/casts/cast_slice_different_sizes.rs b/clippy_lints/src/casts/cast_slice_different_sizes.rs index 27cc5a1c3f04..4d9cc4cacc3e 100644 --- a/clippy_lints/src/casts/cast_slice_different_sizes.rs +++ b/clippy_lints/src/casts/cast_slice_different_sizes.rs @@ -1,10 +1,12 @@ +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::{diagnostics::span_lint_and_then, source}; +use clippy_utils::source; use if_chain::if_chain; use rustc_ast::Mutability; use rustc_hir::{Expr, ExprKind, Node}; use rustc_lint::LateContext; -use rustc_middle::ty::{self, layout::LayoutOf, Ty, TypeAndMut}; +use rustc_middle::ty::layout::LayoutOf; +use rustc_middle::ty::{self, Ty, TypeAndMut}; use super::CAST_SLICE_DIFFERENT_SIZES; diff --git a/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/clippy_lints/src/casts/cast_slice_from_raw_parts.rs index 1233c632a794..5e0123842b04 100644 --- a/clippy_lints/src/casts/cast_slice_from_raw_parts.rs +++ b/clippy_lints/src/casts/cast_slice_from_raw_parts.rs @@ -4,7 +4,8 @@ use clippy_utils::source::snippet_with_context; use clippy_utils::{match_def_path, paths}; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{def_id::DefId, Expr, ExprKind}; +use rustc_hir::def_id::DefId; +use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index d74bd57fe45e..5bf4aa05b8a4 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -9,7 +9,6 @@ mod cast_possible_truncation; mod cast_possible_wrap; mod cast_precision_loss; mod cast_ptr_alignment; -mod cast_ref_to_mut; mod cast_sign_loss; mod cast_slice_different_sizes; mod cast_slice_from_raw_parts; @@ -18,6 +17,7 @@ mod fn_to_numeric_cast; mod fn_to_numeric_cast_any; mod fn_to_numeric_cast_with_truncation; mod ptr_as_ptr; +mod ptr_cast_constness; mod unnecessary_cast; mod utils; @@ -118,9 +118,10 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does /// Checks for casts from an unsigned type to a signed type of - /// the same size. Performing such a cast is a 'no-op' for the compiler, - /// i.e., nothing is changed at the bit level, and the binary representation of - /// the value is reinterpreted. This can cause wrapping if the value is too big + /// the same size, or possibly smaller due to target dependent integers. + /// Performing such a cast is a 'no-op' for the compiler, i.e., nothing is + /// changed at the bit level, and the binary representation of the value is + /// reinterpreted. This can cause wrapping if the value is too big /// for the target signed type. However, the cast works as defined, so this lint /// is `Allow` by default. /// @@ -174,8 +175,8 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for casts to the same type, casts of int literals to integer types - /// and casts of float literals to float types. + /// Checks for casts to the same type, casts of int literals to integer types, casts of float + /// literals to float types and casts between raw pointers without changing type or constness. /// /// ### Why is this bad? /// It's just unnecessary. @@ -330,41 +331,6 @@ declare_clippy_lint! { "casting a function pointer to any integer type" } -declare_clippy_lint! { - /// ### What it does - /// Checks for casts of `&T` to `&mut T` anywhere in the code. - /// - /// ### Why is this bad? - /// It’s basically guaranteed to be undefined behavior. - /// `UnsafeCell` is the only way to obtain aliasable data that is considered - /// mutable. - /// - /// ### Example - /// ```rust,ignore - /// fn x(r: &i32) { - /// unsafe { - /// *(r as *const _ as *mut _) += 1; - /// } - /// } - /// ``` - /// - /// Instead consider using interior mutability types. - /// - /// ```rust - /// use std::cell::UnsafeCell; - /// - /// fn x(r: &UnsafeCell) { - /// unsafe { - /// *r.get() += 1; - /// } - /// } - /// ``` - #[clippy::version = "1.33.0"] - pub CAST_REF_TO_MUT, - correctness, - "a cast of reference to a mutable pointer" -} - declare_clippy_lint! { /// ### What it does /// Checks for expressions where a character literal is cast @@ -399,7 +365,7 @@ declare_clippy_lint! { /// namely `*const T` to `*const U` and `*mut T` to `*mut U`. /// /// ### Why is this bad? - /// Though `as` casts between raw pointers is not terrible, `pointer::cast` is safer because + /// Though `as` casts between raw pointers are not terrible, `pointer::cast` is safer because /// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`. /// /// ### Example @@ -422,6 +388,48 @@ declare_clippy_lint! { "casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`" } +declare_clippy_lint! { + /// ### What it does + /// Checks for `as` casts between raw pointers which change its constness, namely `*const T` to + /// `*mut T` and `*mut T` to `*const T`. + /// + /// ### Why is this bad? + /// Though `as` casts between raw pointers are not terrible, `pointer::cast_mut` and + /// `pointer::cast_const` are safer because they cannot accidentally cast the pointer to another + /// type. + /// + /// ### Example + /// ```rust + /// let ptr: *const u32 = &42_u32; + /// let mut_ptr = ptr as *mut u32; + /// let ptr = mut_ptr as *const u32; + /// ``` + /// Use instead: + /// ```rust + /// let ptr: *const u32 = &42_u32; + /// let mut_ptr = ptr.cast_mut(); + /// let ptr = mut_ptr.cast_const(); + /// ``` +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 97467e4aa (change `clippy::version` to 1.71.0) + #[clippy::version = "1.71.0"] + pub PTR_CAST_CONSTNESS, + pedantic, + "casting using `as` from and to raw pointers to change constness when specialized methods apply" +======= + #[clippy::version = "1.65.0"] + pub PTR_CAST_CONSTNESS, + pedantic, +<<<<<<< HEAD + "TODO" +>>>>>>> 8c191add8 (the implementation!!) +======= + "casting using `as` from and to raw pointers to change constness when specialized methods apply" +>>>>>>> 4ff1cd365 (add description and rename msrv tests) +} + declare_clippy_lint! { /// ### What it does /// Checks for casts from an enum type to an integral type which will definitely truncate the @@ -529,7 +537,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Check for the usage of `as _` conversion using inferred type. + /// Checks for the usage of `as _` conversion using inferred type. /// /// ### Why is this bad? /// The conversion might include lossy conversion and dangerous cast that might go @@ -638,7 +646,7 @@ declare_clippy_lint! { #[clippy::version = "1.66.0"] pub AS_PTR_CAST_MUT, nursery, - "casting the result of the `&self`-taking `as_ptr` to a mutabe pointer" + "casting the result of the `&self`-taking `as_ptr` to a mutable pointer" } declare_clippy_lint! { @@ -680,7 +688,6 @@ impl_lint_pass!(Casts => [ CAST_POSSIBLE_TRUNCATION, CAST_POSSIBLE_WRAP, CAST_LOSSLESS, - CAST_REF_TO_MUT, CAST_PTR_ALIGNMENT, CAST_SLICE_DIFFERENT_SIZES, UNNECESSARY_CAST, @@ -689,6 +696,7 @@ impl_lint_pass!(Casts => [ FN_TO_NUMERIC_CAST_WITH_TRUNCATION, CHAR_LIT_AS_U8, PTR_AS_PTR, + PTR_CAST_CONSTNESS, CAST_ENUM_TRUNCATION, CAST_ENUM_CONSTRUCTOR, CAST_ABS_TO_UNSIGNED, @@ -722,6 +730,15 @@ impl<'tcx> LateLintPass<'tcx> for Casts { return; } cast_slice_from_raw_parts::check(cx, expr, cast_expr, cast_to, &self.msrv); +<<<<<<< HEAD +<<<<<<< HEAD + ptr_cast_constness::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv); +======= + ptr_cast_constness::check(cx, expr, cast_expr, cast_from, cast_to); +>>>>>>> 8c191add8 (the implementation!!) +======= + ptr_cast_constness::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv); +>>>>>>> c5a914b18 (check msrv) as_ptr_cast_mut::check(cx, expr, cast_expr, cast_to); fn_to_numeric_cast_any::check(cx, expr, cast_expr, cast_from, cast_to); fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to); @@ -747,7 +764,6 @@ impl<'tcx> LateLintPass<'tcx> for Casts { } } - cast_ref_to_mut::check(cx, expr); cast_ptr_alignment::check(cx, expr); char_lit_as_u8::check(cx, expr); ptr_as_ptr::check(cx, expr, &self.msrv); diff --git a/clippy_lints/src/casts/ptr_cast_constness.rs b/clippy_lints/src/casts/ptr_cast_constness.rs new file mode 100644 index 000000000000..3a33f681b9a0 --- /dev/null +++ b/clippy_lints/src/casts/ptr_cast_constness.rs @@ -0,0 +1,110 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4ff1cd365 (add description and rename msrv tests) +use clippy_utils::msrvs::POINTER_CAST_CONSTNESS; +use clippy_utils::sugg::Sugg; +use clippy_utils::{diagnostics::span_lint_and_sugg, msrvs::Msrv}; +======= +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::sugg::Sugg; +>>>>>>> 8c191add8 (the implementation!!) +======= +use clippy_utils::sugg::Sugg; +use clippy_utils::{diagnostics::span_lint_and_sugg, msrvs::Msrv}; +>>>>>>> c5a914b18 (check msrv) +======= +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{Msrv, POINTER_CAST_CONSTNESS}; +use clippy_utils::sugg::Sugg; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::{Expr, Mutability}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty, TypeAndMut}; + +use super::PTR_CAST_CONSTNESS; + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +pub(super) fn check<'tcx>( + cx: &LateContext<'_>, + expr: &Expr<'_>, + cast_expr: &Expr<'_>, + cast_from: Ty<'tcx>, + cast_to: Ty<'tcx>, + msrv: &Msrv, +) { + if_chain! { + if msrv.meets(POINTER_CAST_CONSTNESS); + if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, ty: from_ty }) = cast_from.kind(); + if let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, ty: to_ty }) = cast_to.kind(); + if matches!((from_mutbl, to_mutbl), + (Mutability::Not, Mutability::Mut) | (Mutability::Mut, Mutability::Not)); + if from_ty == to_ty; +======= +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { +======= +pub(super) fn check( +======= +pub(super) fn check<'tcx>( +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) + cx: &LateContext<'_>, + expr: &Expr<'_>, + cast_expr: &Expr<'_>, + cast_from: Ty<'tcx>, + cast_to: Ty<'tcx>, + msrv: &Msrv, +) { +>>>>>>> c5a914b18 (check msrv) + if_chain! { + if msrv.meets(POINTER_CAST_CONSTNESS); +<<<<<<< HEAD + if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, .. }) = cast_from.kind(); + if let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, .. }) = cast_to.kind(); +<<<<<<< HEAD + if !matches!((from_mutbl, to_mutbl), + (Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut)); +>>>>>>> 8c191add8 (the implementation!!) +======= + if matches!((from_mutbl, to_mutbl), + (Mutability::Not, Mutability::Mut) | (Mutability::Mut, Mutability::Not)); +>>>>>>> f6a0437e7 (Update clippy_lints/src/casts/ptr_cast_constness.rs) +======= + if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, ty: from_ty }) = cast_from.kind(); + if let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, ty: to_ty }) = cast_to.kind(); + if matches!((from_mutbl, to_mutbl), + (Mutability::Not, Mutability::Mut) | (Mutability::Mut, Mutability::Not)); + if from_ty == to_ty; +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) + then { + let sugg = Sugg::hir(cx, cast_expr, "_"); + let constness = match *to_mutbl { + Mutability::Not => "const", + Mutability::Mut => "mut", + }; + + span_lint_and_sugg( + cx, + PTR_CAST_CONSTNESS, + expr.span, +<<<<<<< HEAD +<<<<<<< HEAD + "`as` casting between raw pointers while changing only its constness", +======= + "`as` casting between raw pointers while changing its constness", +>>>>>>> 8c191add8 (the implementation!!) +======= + "`as` casting between raw pointers while changing only its constness", +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) + &format!("try `pointer::cast_{constness}`, a safer alternative"), + format!("{}.cast_{constness}()", sugg.maybe_par()), + Applicability::MachineApplicable, + ); + } + } +} diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs index 7e23318076cf..4e8cf5ef31ec 100644 --- a/clippy_lints/src/casts/unnecessary_cast.rs +++ b/clippy_lints/src/casts/unnecessary_cast.rs @@ -1,18 +1,42 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::numeric_literal::NumericLiteral; use clippy_utils::source::snippet_opt; -use clippy_utils::{get_parent_expr, path_to_local}; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::visitors::{for_each_expr, Visitable}; +use clippy_utils::{get_parent_expr, get_parent_node, is_hir_ty_cfg_dependant, is_ty_alias, path_to_local}; +======= +use clippy_utils::{get_parent_expr, is_ty_alias, path_to_local}; +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= +use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias, path_to_local}; +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) use if_chain::if_chain; use rustc_ast::{LitFloatType, LitIntType, LitKind}; use rustc_errors::Applicability; +<<<<<<< HEAD +use rustc_hir::def::{DefKind, Res}; +======= use rustc_hir::def::Res; -use rustc_hir::{Expr, ExprKind, Lit, QPath, TyKind, UnOp}; +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= +use clippy_utils::visitors::{for_each_expr, Visitable}; +use clippy_utils::{get_parent_expr, get_parent_node, is_hir_ty_cfg_dependant, is_ty_alias, path_to_local}; +use if_chain::if_chain; +use rustc_ast::{LitFloatType, LitIntType, LitKind}; +use rustc_errors::Applicability; +use rustc_hir::def::{DefKind, Res}; +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) +use rustc_hir::{Expr, ExprKind, Lit, Node, Path, QPath, TyKind, UnOp}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, FloatTy, InferTy, Ty}; +use std::ops::ControlFlow; use super::UNNECESSARY_CAST; +#[expect(clippy::too_many_lines)] pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &Expr<'tcx>, @@ -20,19 +44,136 @@ pub(super) fn check<'tcx>( cast_from: Ty<'tcx>, cast_to: Ty<'tcx>, ) -> bool { + let cast_str = snippet_opt(cx, cast_expr.span).unwrap_or_default(); + + if_chain! { + if let ty::RawPtr(..) = cast_from.kind(); + // check both mutability and type are the same + if cast_from.kind() == cast_to.kind(); + if let ExprKind::Cast(_, cast_to_hir) = expr.kind; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) + // Ignore casts to e.g. type aliases and infer types + // - p as pointer_alias + // - p as _ + if let TyKind::Ptr(to_pointee) = cast_to_hir.kind; +<<<<<<< HEAD + then { + match to_pointee.ty.kind { + // Ignore casts to pointers that are aliases or cfg dependant, e.g. + // - p as *const std::ffi::c_char (alias) + // - p as *const std::os::raw::c_char (cfg dependant) + TyKind::Path(qpath) => { + if is_ty_alias(&qpath) || is_hir_ty_cfg_dependant(cx, to_pointee.ty) { + return false; + } + }, + // Ignore `p as *const _` + TyKind::Infer => return false, + _ => {}, +======= + then { + if_chain! { + if let TyKind::Path(qpath) = cast_to_hir.kind; + if is_ty_alias(&qpath); + then { + return false; + } + } + + if let TyKind::Infer = cast_to_hir.kind { + return false; +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + then { + match to_pointee.ty.kind { + // Ignore casts to pointers that are aliases or cfg dependant, e.g. + // - p as *const std::ffi::c_char (alias) + // - p as *const std::os::raw::c_char (cfg dependant) + TyKind::Path(qpath) => { + if is_ty_alias(&qpath) || is_hir_ty_cfg_dependant(cx, to_pointee.ty) { + return false; + } + }, + // Ignore `p as *const _` + TyKind::Infer => return false, + _ => {}, +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) + } + + span_lint_and_sugg( + cx, + UNNECESSARY_CAST, + expr.span, + &format!("casting raw pointers to the same type and constness is unnecessary (`{cast_from}` -> `{cast_to}`)"), + "try", + cast_str.clone(), + Applicability::MaybeIncorrect, + ); + } + } + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + // skip cast of local that is a type alias +======= + // skip cast of local to type alias +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + // skip cast of local that is a type alias +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + if let ExprKind::Cast(inner, ..) = expr.kind + && let ExprKind::Path(qpath) = inner.kind + && let QPath::Resolved(None, Path { res, .. }) = qpath + && let Res::Local(hir_id) = res + && let parent = cx.tcx.hir().get_parent(*hir_id) + && let Node::Local(local) = parent + { + if let Some(ty) = local.ty + && let TyKind::Path(qpath) = ty.kind + && is_ty_alias(&qpath) + { + return false; + } + + if let Some(expr) = local.init + && let ExprKind::Cast(.., cast_to) = expr.kind + && let TyKind::Path(qpath) = cast_to.kind + && is_ty_alias(&qpath) + { + return false; + } + } + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + // skip cast of fn call that returns type alias + if let ExprKind::Cast(inner, ..) = expr.kind && is_cast_from_ty_alias(cx, inner, cast_from) { + return false; + } + + // skip cast to non-primitive type +======= // skip non-primitive type cast +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + // skip cast to non-primitive type +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) if_chain! { if let ExprKind::Cast(_, cast_to) = expr.kind; if let TyKind::Path(QPath::Resolved(_, path)) = &cast_to.kind; if let Res::PrimTy(_) = path.res; then {} else { - return false + return false; } } - let cast_str = snippet_opt(cx, cast_expr.span).unwrap_or_default(); - if let Some(lit) = get_numeric_literal(cast_expr) { let literal_str = &cast_str; @@ -162,3 +303,61 @@ fn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 { _ => 0, } } + +/// Finds whether an `Expr` returns a type alias. +/// +/// TODO: Maybe we should move this to `clippy_utils` so others won't need to go down this dark, +/// dark path reimplementing this (or something similar). +fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx>, cast_from: Ty<'tcx>) -> bool { + for_each_expr(expr, |expr| { + // Calls are a `Path`, and usage of locals are a `Path`. So, this checks + // - call() as i32 + // - local as i32 + if let ExprKind::Path(qpath) = expr.kind { + let res = cx.qpath_res(&qpath, expr.hir_id); + // Function call + if let Res::Def(DefKind::Fn, def_id) = res { + let Some(snippet) = snippet_opt(cx, cx.tcx.def_span(def_id)) else { + return ControlFlow::Continue(()); + }; + // This is the worst part of this entire function. This is the only way I know of to + // check whether a function returns a type alias. Sure, you can get the return type + // from a function in the current crate as an hir ty, but how do you get it for + // external functions?? Simple: It's impossible. So, we check whether a part of the + // function's declaration snippet is exactly equal to the `Ty`. That way, we can + // see whether it's a type alias. + // + // Will this work for more complex types? Probably not! + if !snippet + .split("->") + .skip(0) + .map(|s| { + s.trim() == cast_from.to_string() + || s.split("where").any(|ty| ty.trim() == cast_from.to_string()) + }) + .any(|a| a) + { + return ControlFlow::Break(()); + } + // Local usage + } else if let Res::Local(hir_id) = res + && let Some(parent) = get_parent_node(cx.tcx, hir_id) + && let Node::Local(l) = parent + { + if let Some(e) = l.init && is_cast_from_ty_alias(cx, e, cast_from) { + return ControlFlow::Break::<()>(()); + } + + if let Some(ty) = l.ty + && let TyKind::Path(qpath) = ty.kind + && is_ty_alias(&qpath) + { + return ControlFlow::Break::<()>(()); + } + } + } + + ControlFlow::Continue(()) + }) + .is_some() +} diff --git a/clippy_lints/src/collection_is_never_read.rs b/clippy_lints/src/collection_is_never_read.rs index 5e2eb5789f62..ac5ac542cf94 100644 --- a/clippy_lints/src/collection_is_never_read.rs +++ b/clippy_lints/src/collection_is_never_read.rs @@ -37,7 +37,7 @@ declare_clippy_lint! { /// println!("{sample}"); /// } /// ``` - #[clippy::version = "1.69.0"] + #[clippy::version = "1.70.0"] pub COLLECTION_IS_NEVER_READ, nursery, "a collection is never queried" diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 970f50049935..e3a09636e249 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -10,8 +10,7 @@ use core::iter; use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::def_id::DefIdSet; -use rustc_hir::intravisit; -use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, Stmt, StmtKind}; +use rustc_hir::{intravisit, BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::query::Key; use rustc_session::{declare_tool_lint, impl_lint_pass}; @@ -591,7 +590,7 @@ fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>], ignored_ty_ids: &De conds, |e| hash_expr(cx, e), |lhs, rhs| { - // Ignore eq_expr side effects iff one of the expressin kind is a method call + // Ignore eq_expr side effects iff one of the expression kind is a method call // and the caller is not a mutable, including inner mutable type. if let ExprKind::MethodCall(_, caller, _, _) = lhs.kind { if method_caller_is_mutable(cx, caller, ignored_ty_ids) { diff --git a/clippy_lints/src/crate_in_macro_def.rs b/clippy_lints/src/crate_in_macro_def.rs index 7436e9ce811b..726674d88f17 100644 --- a/clippy_lints/src/crate_in_macro_def.rs +++ b/clippy_lints/src/crate_in_macro_def.rs @@ -5,7 +5,8 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::{symbol::sym, Span}; +use rustc_span::symbol::sym; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/dbg_macro.rs b/clippy_lints/src/dbg_macro.rs index 799e71e847a9..2a6ae8c92fca 100644 --- a/clippy_lints/src/dbg_macro.rs +++ b/clippy_lints/src/dbg_macro.rs @@ -3,10 +3,24 @@ use clippy_utils::macros::root_macro_call_first_node; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{is_in_cfg_test, is_in_test_function}; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind}; -use rustc_lint::{LateContext, LateLintPass}; +<<<<<<< HEAD +<<<<<<< HEAD +use rustc_hir::{Expr, ExprKind, Node}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::sym; +use rustc_span::{sym, BytePos, Pos, Span}; +======= +use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::{sym, Span}; +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= +use rustc_hir::{Expr, ExprKind, Node}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::{sym, BytePos, Pos, Span}; +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) declare_clippy_lint! { /// ### What it does @@ -31,6 +45,43 @@ declare_clippy_lint! { "`dbg!` macro is intended as a debugging tool" } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +/// Gets the span of the statement up to the next semicolon, if and only if the next +/// non-whitespace character actually is a semicolon. +/// E.g. +/// ```rust,ignore +/// +/// dbg!(); +/// ^^^^^^^ this span is returned +/// +/// foo!(dbg!()); +/// no span is returned +/// ``` +fn span_including_semi(cx: &LateContext<'_>, span: Span) -> Option { + let sm = cx.sess().source_map(); + let sf = sm.lookup_source_file(span.hi()); + let src = sf.src.as_ref()?.get(span.hi().to_usize()..)?; + let first_non_whitespace = src.find(|c: char| !c.is_whitespace())?; + + if src.as_bytes()[first_non_whitespace] == b';' { + let hi = span.hi() + BytePos::from_usize(first_non_whitespace + 1); + Some(span.with_hi(hi)) + } else { + None + } +<<<<<<< HEAD +======= +fn span_including_semi(cx: &LateContext<'_>, span: Span) -> Span { + let span = cx.sess().source_map().span_extend_to_next_char(span, ';', true); + span.with_hi(span.hi() + rustc_span::BytePos(1)) +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +} + #[derive(Copy, Clone)] pub struct DbgMacro { allow_dbg_in_tests: bool, @@ -55,13 +106,44 @@ impl LateLintPass<'_> for DbgMacro { return; } let mut applicability = Applicability::MachineApplicable; - let suggestion = match expr.peel_drop_temps().kind { + + let (sugg_span, suggestion) = match expr.peel_drop_temps().kind { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) // dbg!() - ExprKind::Block(_, _) => String::new(), - // dbg!(1) - ExprKind::Match(val, ..) => { - snippet_with_applicability(cx, val.span.source_callsite(), "..", &mut applicability).to_string() + ExprKind::Block(..) => { + // If the `dbg!` macro is a "free" statement and not contained within other expressions, + // remove the whole statement. + if let Some(Node::Stmt(stmt)) = cx.tcx.hir().find_parent(expr.hir_id) + && let Some(span) = span_including_semi(cx, stmt.span.source_callsite()) + { + (span, String::new()) + } else { + (macro_call.span, String::from("()")) + } +<<<<<<< HEAD +======= + ExprKind::Block(..) => match cx.tcx.hir().find_parent(expr.hir_id) { + // dbg!() as a standalone statement, suggest removing the whole statement entirely + Some(Node::Stmt( + stmt @ Stmt { + kind: StmtKind::Semi(_), + .. + }, + )) => (span_including_semi(cx, stmt.span.source_callsite()), String::new()), + // empty dbg!() in arbitrary position (e.g. `foo(dbg!())`), suggest replacing with `foo(())` + _ => (macro_call.span, String::from("()")), +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) }, + // dbg!(1) + ExprKind::Match(val, ..) => ( + macro_call.span, + snippet_with_applicability(cx, val.span.source_callsite(), "..", &mut applicability).to_string(), + ), // dbg!(2, 3) ExprKind::Tup( [ @@ -82,7 +164,7 @@ impl LateLintPass<'_> for DbgMacro { "..", &mut applicability, ); - format!("({snippet})") + (macro_call.span, format!("({snippet})")) }, _ => return, }; @@ -90,7 +172,7 @@ impl LateLintPass<'_> for DbgMacro { span_lint_and_sugg( cx, DBG_MACRO, - macro_call.span, + sugg_span, "the `dbg!` macro is intended as a debugging tool", "remove the invocation before committing it to a version control system", suggestion, diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index c3e51a354aa5..4292861a1ec0 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -3,6 +3,8 @@ // Manual edits will be overwritten. pub(crate) static LINTS: &[&crate::LintInfo] = &[ + #[cfg(feature = "internal")] + crate::utils::internal_lints::almost_standard_lint_formulation::ALMOST_STANDARD_LINT_FORMULATION_INFO, #[cfg(feature = "internal")] crate::utils::internal_lints::clippy_lints_internal::CLIPPY_LINTS_INTERNAL_INFO, #[cfg(feature = "internal")] @@ -38,6 +40,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::allow_attributes::ALLOW_ATTRIBUTES_INFO, crate::almost_complete_range::ALMOST_COMPLETE_RANGE_INFO, crate::approx_const::APPROX_CONSTANT_INFO, + crate::arc_with_non_send_sync::ARC_WITH_NON_SEND_SYNC_INFO, crate::as_conversions::AS_CONVERSIONS_INFO, crate::asm_syntax::INLINE_ASM_X86_ATT_SYNTAX_INFO, crate::asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX_INFO, @@ -48,9 +51,12 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::attrs::BLANKET_CLIPPY_RESTRICTION_LINTS_INFO, crate::attrs::DEPRECATED_CFG_ATTR_INFO, crate::attrs::DEPRECATED_SEMVER_INFO, + crate::attrs::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO, crate::attrs::EMPTY_LINE_AFTER_OUTER_ATTR_INFO, crate::attrs::INLINE_ALWAYS_INFO, + crate::attrs::MAYBE_MISUSED_CFG_INFO, crate::attrs::MISMATCHED_TARGET_OS_INFO, + crate::attrs::NON_MINIMAL_CFG_INFO, crate::attrs::USELESS_ATTRIBUTE_INFO, crate::await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE_INFO, crate::await_holding_invalid::AWAIT_HOLDING_LOCK_INFO, @@ -79,7 +85,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::casts::CAST_POSSIBLE_WRAP_INFO, crate::casts::CAST_PRECISION_LOSS_INFO, crate::casts::CAST_PTR_ALIGNMENT_INFO, - crate::casts::CAST_REF_TO_MUT_INFO, crate::casts::CAST_SIGN_LOSS_INFO, crate::casts::CAST_SLICE_DIFFERENT_SIZES_INFO, crate::casts::CAST_SLICE_FROM_RAW_PARTS_INFO, @@ -88,6 +93,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::casts::FN_TO_NUMERIC_CAST_ANY_INFO, crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO, crate::casts::PTR_AS_PTR_INFO, + crate::casts::PTR_CAST_CONSTNESS_INFO, crate::casts::UNNECESSARY_CAST_INFO, crate::checked_conversions::CHECKED_CONVERSIONS_INFO, crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO, @@ -105,6 +111,15 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::dbg_macro::DBG_MACRO_INFO, crate::default::DEFAULT_TRAIT_ACCESS_INFO, crate::default::FIELD_REASSIGN_WITH_DEFAULT_INFO, +<<<<<<< HEAD +<<<<<<< HEAD + crate::default_constructed_unit_structs::DEFAULT_CONSTRUCTED_UNIT_STRUCTS_INFO, +======= + crate::default_constructed_unit_struct::DEFAULT_CONSTRUCTED_UNIT_STRUCT_INFO, +>>>>>>> 942813856 (adds lint to detect construction of unit struct using `default`) +======= + crate::default_constructed_unit_structs::DEFAULT_CONSTRUCTED_UNIT_STRUCTS_INFO, +>>>>>>> 4e0490363 (rename to plural form) crate::default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY_INFO, crate::default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK_INFO, crate::default_union_representation::DEFAULT_UNION_REPRESENTATION_INFO, @@ -131,18 +146,21 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::doc::NEEDLESS_DOCTEST_MAIN_INFO, crate::doc::UNNECESSARY_SAFETY_DOC_INFO, crate::double_parens::DOUBLE_PARENS_INFO, - crate::drop_forget_ref::DROP_COPY_INFO, crate::drop_forget_ref::DROP_NON_DROP_INFO, - crate::drop_forget_ref::DROP_REF_INFO, - crate::drop_forget_ref::FORGET_COPY_INFO, crate::drop_forget_ref::FORGET_NON_DROP_INFO, - crate::drop_forget_ref::FORGET_REF_INFO, + crate::drop_forget_ref::MEM_FORGET_INFO, +<<<<<<< HEAD +======= crate::drop_forget_ref::UNDROPPED_MANUALLY_DROPS_INFO, +>>>>>>> b6f194b48 (move to `drop_forget_ref`) crate::duplicate_mod::DUPLICATE_MOD_INFO, crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO, crate::empty_drop::EMPTY_DROP_INFO, crate::empty_enum::EMPTY_ENUM_INFO, crate::empty_structs_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS_INFO, + crate::endian_bytes::BIG_ENDIAN_BYTES_INFO, + crate::endian_bytes::HOST_ENDIAN_BYTES_INFO, + crate::endian_bytes::LITTLE_ENDIAN_BYTES_INFO, crate::entry::MAP_ENTRY_INFO, crate::enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT_INFO, crate::enum_variants::ENUM_VARIANT_NAMES_INFO, @@ -154,6 +172,16 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS_INFO, crate::excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS_INFO, crate::excessive_bools::STRUCT_EXCESSIVE_BOOLS_INFO, +<<<<<<< HEAD +<<<<<<< HEAD + crate::excessive_nesting::EXCESSIVE_NESTING_INFO, +======= + crate::excessive_width::EXCESSIVE_INDENTATION_INFO, + crate::excessive_width::EXCESSIVE_WIDTH_INFO, +>>>>>>> 97c10075e (add the `excessive_*` style lints) +======= + crate::excessive_nesting::EXCESSIVE_NESTING_INFO, +>>>>>>> e68dbc330 (add `excessive_nesting`) crate::exhaustive_items::EXHAUSTIVE_ENUMS_INFO, crate::exhaustive_items::EXHAUSTIVE_STRUCTS_INFO, crate::exit::EXIT_INFO, @@ -164,7 +192,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::float_literal::LOSSY_FLOAT_LITERAL_INFO, crate::floating_point_arithmetic::IMPRECISE_FLOPS_INFO, crate::floating_point_arithmetic::SUBOPTIMAL_FLOPS_INFO, - crate::fn_null_check::FN_NULL_CHECK_INFO, crate::format::USELESS_FORMAT_INFO, crate::format_args::FORMAT_IN_FORMAT_ARGS_INFO, crate::format_args::TO_STRING_IN_FORMAT_ARGS_INFO, @@ -199,6 +226,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::implicit_saturating_add::IMPLICIT_SATURATING_ADD_INFO, crate::implicit_saturating_sub::IMPLICIT_SATURATING_SUB_INFO, crate::inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR_INFO, + crate::incorrect_impls::INCORRECT_CLONE_IMPL_ON_COPY_TYPE_INFO, + crate::incorrect_impls::INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE_INFO, crate::index_refutable_slice::INDEX_REFUTABLE_SLICE_INFO, crate::indexing_slicing::INDEXING_SLICING_INFO, crate::indexing_slicing::OUT_OF_BOUNDS_INDEXING_INFO, @@ -213,14 +242,15 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::instant_subtraction::UNCHECKED_DURATION_SUBTRACTION_INFO, crate::int_plus_one::INT_PLUS_ONE_INFO, crate::invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS_INFO, - crate::invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED_INFO, crate::items_after_statements::ITEMS_AFTER_STATEMENTS_INFO, + crate::items_after_test_module::ITEMS_AFTER_TEST_MODULE_INFO, crate::iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR_INFO, crate::large_const_arrays::LARGE_CONST_ARRAYS_INFO, crate::large_enum_variant::LARGE_ENUM_VARIANT_INFO, crate::large_futures::LARGE_FUTURES_INFO, crate::large_include_file::LARGE_INCLUDE_FILE_INFO, crate::large_stack_arrays::LARGE_STACK_ARRAYS_INFO, + crate::large_stack_frames::LARGE_STACK_FRAMES_INFO, crate::len_zero::COMPARISON_TO_EMPTY_INFO, crate::len_zero::LEN_WITHOUT_IS_EMPTY_INFO, crate::len_zero::LEN_ZERO_INFO, @@ -248,6 +278,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::loops::MANUAL_FIND_INFO, crate::loops::MANUAL_FLATTEN_INFO, crate::loops::MANUAL_MEMCPY_INFO, + crate::loops::MANUAL_WHILE_LET_SOME_INFO, crate::loops::MISSING_SPIN_LOOP_INFO, crate::loops::MUT_RANGE_BOUND_INFO, crate::loops::NEEDLESS_RANGE_LOOP_INFO, @@ -263,10 +294,28 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::manual_async_fn::MANUAL_ASYNC_FN_INFO, crate::manual_bits::MANUAL_BITS_INFO, crate::manual_clamp::MANUAL_CLAMP_INFO, + crate::manual_float_methods::MANUAL_IS_FINITE_INFO, + crate::manual_float_methods::MANUAL_IS_INFINITE_INFO, crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO, crate::manual_let_else::MANUAL_LET_ELSE_INFO, crate::manual_main_separator_str::MANUAL_MAIN_SEPARATOR_STR_INFO, crate::manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE_INFO, +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= + crate::manual_partial_ord_impl::MANUAL_PARTIAL_ORD_IMPL_INFO, +>>>>>>> 2a1fd22f8 (implement `manual_partial_ord_impl`) +======= +>>>>>>> 004e89d4c (rename to `manual_partial_ord_and_ord_impl`) + crate::manual_range_patterns::MANUAL_RANGE_PATTERNS_INFO, +======= + crate::manual_range_pattern::MANUAL_RANGE_PATTERN_INFO, +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) +======= + crate::manual_range_patterns::MANUAL_RANGE_PATTERNS_INFO, +>>>>>>> b592d3996 (manual_range_pattern -> manual_range_patterns) crate::manual_rem_euclid::MANUAL_REM_EUCLID_INFO, crate::manual_retain::MANUAL_RETAIN_INFO, crate::manual_slice_size_calculation::MANUAL_SLICE_SIZE_CALCULATION_INFO, @@ -300,7 +349,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::matches::TRY_ERR_INFO, crate::matches::WILDCARD_ENUM_MATCH_ARM_INFO, crate::matches::WILDCARD_IN_OR_PATTERNS_INFO, - crate::mem_forget::MEM_FORGET_INFO, crate::mem_replace::MEM_REPLACE_OPTION_WITH_NONE_INFO, crate::mem_replace::MEM_REPLACE_WITH_DEFAULT_INFO, crate::mem_replace::MEM_REPLACE_WITH_UNINIT_INFO, @@ -312,10 +360,10 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::CHARS_NEXT_CMP_INFO, crate::methods::CLEAR_WITH_DRAIN_INFO, crate::methods::CLONED_INSTEAD_OF_COPIED_INFO, - crate::methods::CLONE_DOUBLE_REF_INFO, crate::methods::CLONE_ON_COPY_INFO, crate::methods::CLONE_ON_REF_PTR_INFO, crate::methods::COLLAPSIBLE_STR_REPLACE_INFO, + crate::methods::DRAIN_COLLECT_INFO, crate::methods::ERR_EXPECT_INFO, crate::methods::EXPECT_FUN_CALL_INFO, crate::methods::EXPECT_USED_INFO, @@ -347,12 +395,15 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::ITER_OVEREAGER_CLONED_INFO, crate::methods::ITER_SKIP_NEXT_INFO, crate::methods::ITER_WITH_DRAIN_INFO, + crate::methods::JOIN_ABSOLUTE_PATHS_INFO, crate::methods::MANUAL_FILTER_MAP_INFO, crate::methods::MANUAL_FIND_MAP_INFO, + crate::methods::MANUAL_NEXT_BACK_INFO, crate::methods::MANUAL_OK_OR_INFO, crate::methods::MANUAL_SATURATING_ARITHMETIC_INFO, crate::methods::MANUAL_SPLIT_ONCE_INFO, crate::methods::MANUAL_STR_REPEAT_INFO, + crate::methods::MANUAL_TRY_FOLD_INFO, crate::methods::MAP_CLONE_INFO, crate::methods::MAP_COLLECT_RESULT_UNIT_INFO, crate::methods::MAP_ERR_IGNORE_INFO, @@ -376,8 +427,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::OR_FUN_CALL_INFO, crate::methods::OR_THEN_UNWRAP_INFO, crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO, - crate::methods::PATH_JOIN_CORRECTION_INFO, crate::methods::RANGE_ZIP_WITH_LEN_INFO, + crate::methods::READ_LINE_WITHOUT_TRIM_INFO, crate::methods::REPEAT_ONCE_INFO, crate::methods::RESULT_MAP_OR_INTO_OPTION_INFO, crate::methods::SEARCH_IS_SOME_INFO, @@ -393,6 +444,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::SUSPICIOUS_MAP_INFO, crate::methods::SUSPICIOUS_SPLITN_INFO, crate::methods::SUSPICIOUS_TO_OWNED_INFO, + crate::methods::TYPE_ID_ON_BOX_INFO, crate::methods::UNINIT_ASSUMED_INIT_INFO, crate::methods::UNIT_HASH_INFO, crate::methods::UNNECESSARY_FILTER_MAP_INFO, @@ -400,6 +452,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::UNNECESSARY_FOLD_INFO, crate::methods::UNNECESSARY_JOIN_INFO, crate::methods::UNNECESSARY_LAZY_EVALUATIONS_INFO, + crate::methods::UNNECESSARY_LITERAL_UNWRAP_INFO, crate::methods::UNNECESSARY_SORT_BY_INFO, crate::methods::UNNECESSARY_TO_OWNED_INFO, crate::methods::UNWRAP_OR_ELSE_DEFAULT_INFO, @@ -409,6 +462,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::VERBOSE_FILE_READS_INFO, crate::methods::WRONG_SELF_CONVENTION_INFO, crate::methods::ZST_OFFSET_INFO, + crate::min_ident_chars::MIN_IDENT_CHARS_INFO, crate::minmax::MIN_MAX_INFO, crate::misc::SHORT_CIRCUIT_STATEMENT_INFO, crate::misc::TOPLEVEL_REF_ARG_INFO, @@ -418,6 +472,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::misc_early::DOUBLE_NEG_INFO, crate::misc_early::DUPLICATE_UNDERSCORE_ARGUMENT_INFO, crate::misc_early::MIXED_CASE_HEX_LITERALS_INFO, + crate::misc_early::REDUNDANT_AT_REST_PATTERN_INFO, crate::misc_early::REDUNDANT_PATTERN_INFO, crate::misc_early::SEPARATED_LITERAL_SUFFIX_INFO, crate::misc_early::UNNEEDED_FIELD_PATTERN_INFO, @@ -429,6 +484,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::missing_const_for_fn::MISSING_CONST_FOR_FN_INFO, crate::missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS_INFO, crate::missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES_INFO, + crate::missing_fields_in_debug::MISSING_FIELDS_IN_DEBUG_INFO, crate::missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS_INFO, crate::missing_trait_methods::MISSING_TRAIT_METHODS_INFO, crate::mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION_INFO, @@ -446,11 +502,15 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE_INFO, crate::needless_bool::BOOL_COMPARISON_INFO, crate::needless_bool::NEEDLESS_BOOL_INFO, + crate::needless_bool::NEEDLESS_BOOL_ASSIGN_INFO, crate::needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE_INFO, crate::needless_continue::NEEDLESS_CONTINUE_INFO, + crate::needless_else::NEEDLESS_ELSE_INFO, crate::needless_for_each::NEEDLESS_FOR_EACH_INFO, + crate::needless_if::NEEDLESS_IF_INFO, crate::needless_late_init::NEEDLESS_LATE_INIT_INFO, crate::needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS_INFO, + crate::needless_pass_by_ref_mut::NEEDLESS_PASS_BY_REF_MUT_INFO, crate::needless_pass_by_value::NEEDLESS_PASS_BY_VALUE_INFO, crate::needless_question_mark::NEEDLESS_QUESTION_MARK_INFO, crate::needless_update::NEEDLESS_UPDATE_INFO, @@ -475,7 +535,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::operators::ARITHMETIC_SIDE_EFFECTS_INFO, crate::operators::ASSIGN_OP_PATTERN_INFO, crate::operators::BAD_BIT_MASK_INFO, - crate::operators::CMP_NAN_INFO, crate::operators::CMP_OWNED_INFO, crate::operators::DOUBLE_COMPARISONS_INFO, crate::operators::DURATION_SUBSEC_INFO, @@ -487,7 +546,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::operators::FLOAT_EQUALITY_WITHOUT_ABS_INFO, crate::operators::IDENTITY_OP_INFO, crate::operators::INEFFECTIVE_BIT_MASK_INFO, - crate::operators::INTEGER_ARITHMETIC_INFO, crate::operators::INTEGER_DIVISION_INFO, crate::operators::MISREFACTORED_ASSIGN_OP_INFO, crate::operators::MODULO_ARITHMETIC_INFO, @@ -525,6 +583,16 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::ranges::RANGE_MINUS_ONE_INFO, crate::ranges::RANGE_PLUS_ONE_INFO, crate::ranges::REVERSED_EMPTY_RANGES_INFO, +<<<<<<< HEAD +<<<<<<< HEAD + crate::raw_strings::NEEDLESS_RAW_STRINGS_INFO, +======= + crate::raw_strings::NEEDLESS_RAW_STRING_INFO, +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= + crate::raw_strings::NEEDLESS_RAW_STRINGS_INFO, +>>>>>>> 8cb6c8699 (change category and refactor) + crate::raw_strings::NEEDLESS_RAW_STRING_HASHES_INFO, crate::rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT_INFO, crate::read_zero_byte_vec::READ_ZERO_BYTE_VEC_INFO, crate::redundant_async_block::REDUNDANT_ASYNC_BLOCK_INFO, @@ -536,7 +604,9 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::redundant_slicing::DEREF_BY_SLICING_INFO, crate::redundant_slicing::REDUNDANT_SLICING_INFO, crate::redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES_INFO, + crate::redundant_type_annotations::REDUNDANT_TYPE_ANNOTATIONS_INFO, crate::ref_option_ref::REF_OPTION_REF_INFO, + crate::ref_patterns::REF_PATTERNS_INFO, crate::reference::DEREF_ADDROF_INFO, crate::regex::INVALID_REGEX_INFO, crate::regex::TRIVIAL_REGEX_INFO, @@ -553,8 +623,30 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::shadow::SHADOW_SAME_INFO, crate::shadow::SHADOW_UNRELATED_INFO, crate::significant_drop_tightening::SIGNIFICANT_DROP_TIGHTENING_INFO, +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) + crate::single_call_fn::SINGLE_CALL_FN_INFO, + crate::single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES_INFO, + crate::single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS_INFO, +<<<<<<< HEAD +<<<<<<< HEAD + crate::single_range_in_vec_init::SINGLE_RANGE_IN_VEC_INIT_INFO, +======= + crate::single_letter_idents::SINGLE_LETTER_IDENTS_INFO, +>>>>>>> 52cfc997a (Add lint `single_letter_idents`) +======= + crate::single_char_idents::SINGLE_CHAR_IDENTS_INFO, +======= +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) crate::single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES_INFO, crate::single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS_INFO, +>>>>>>> e2ecb132a (rename the lint) +======= + crate::single_range_in_vec_init::SINGLE_RANGE_IN_VEC_INIT_INFO, +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) crate::size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT_INFO, crate::size_of_ref::SIZE_OF_REF_INFO, crate::slow_vector_initialization::SLOW_VECTOR_INITIALIZATION_INFO, @@ -602,6 +694,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::transmute::UNSOUND_COLLECTION_TRANSMUTE_INFO, crate::transmute::USELESS_TRANSMUTE_INFO, crate::transmute::WRONG_TRANSMUTE_INFO, + crate::tuple_array_conversions::TUPLE_ARRAY_CONVERSIONS_INFO, crate::types::BORROWED_BOX_INFO, crate::types::BOX_COLLECTION_INFO, crate::types::LINKEDLIST_INFO, @@ -644,6 +737,9 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::useless_conversion::USELESS_CONVERSION_INFO, crate::vec::USELESS_VEC_INFO, crate::vec_init_then_push::VEC_INIT_THEN_PUSH_INFO, + crate::visibility::NEEDLESS_PUB_SELF_INFO, + crate::visibility::PUB_WITHOUT_SHORTHAND_INFO, + crate::visibility::PUB_WITH_SHORTHAND_INFO, crate::wildcard_imports::ENUM_GLOB_USE_INFO, crate::wildcard_imports::WILDCARD_IMPORTS_INFO, crate::write::PRINTLN_EMPTY_STRING_INFO, diff --git a/clippy_lints/src/default_constructed_unit_structs.rs b/clippy_lints/src/default_constructed_unit_structs.rs new file mode 100644 index 000000000000..8339503a0efb --- /dev/null +++ b/clippy_lints/src/default_constructed_unit_structs.rs @@ -0,0 +1,210 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::{diagnostics::span_lint_and_sugg, match_def_path, paths}; +======= +use clippy_utils::{diagnostics::span_lint_and_sugg, is_from_proc_macro, match_def_path, paths}; +>>>>>>> 4e0490363 (rename to plural form) +======= +use clippy_utils::{diagnostics::span_lint_and_sugg, match_def_path, paths}; +>>>>>>> 68eb864c9 (Ignore expressions from macros in default_constructed_unit_structs) +======= +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::{diagnostics::span_lint_and_sugg, match_def_path, paths}; +======= +use clippy_utils::{diagnostics::span_lint_and_sugg, is_from_proc_macro, match_def_path, paths}; +>>>>>>> 7e9abb311 (Merge commit '371120bdbf58a331db5dcfb2d9cddc040f486de8' into clippyup) +======= +use clippy_utils::{diagnostics::span_lint_and_sugg, match_def_path, paths}; +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +======= +use clippy_utils::{diagnostics::span_lint_and_sugg, is_ty_alias, match_def_path, paths}; +>>>>>>> e6dc0efc0 (Merge commit '30448e8cf98d4754350db0c959644564f317bc0f' into clippyup) +======= +use clippy_utils::{diagnostics::span_lint_and_sugg, is_ty_alias, match_def_path, paths}; +>>>>>>> 8c82486ea ([`default_constructed_unit_structs`]: do not lint type aliases) +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +use hir::{def::Res, ExprKind}; +======= +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::{is_ty_alias, match_def_path, paths}; +use hir::def::Res; +use hir::ExprKind; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +======= +use clippy_utils::{diagnostics::span_lint_and_sugg, match_def_path, paths}; +use hir::{def::Res, ExprKind}; +>>>>>>> e4f5d83fa (Fixed formatting.) +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does +<<<<<<< HEAD + /// Checks for construction on unit struct using `default`. +======= + /// Check for construction on unit struct using `default`. +>>>>>>> e4f5d83fa (Fixed formatting.) + /// + /// ### Why is this bad? + /// This adds code complexity and an unnecessary function call. + /// + /// ### Example + /// ```rust +<<<<<<< HEAD +<<<<<<< HEAD + /// # use std::marker::PhantomData; +======= +>>>>>>> 4e0490363 (rename to plural form) +======= + /// # use std::marker::PhantomData; +>>>>>>> 48ae5a071 (fix lint docs) + /// #[derive(Default)] + /// struct S { + /// _marker: PhantomData + /// } + /// + /// let _: S = S { + /// _marker: PhantomData::default() + /// }; + /// ``` + /// Use instead: + /// ```rust +<<<<<<< HEAD +<<<<<<< HEAD + /// # use std::marker::PhantomData; + /// struct S { + /// _marker: PhantomData + /// } + /// + /// let _: S = S { + /// _marker: PhantomData + /// }; +======= + /// let _: S = Something { + /// _marker: PhantomData + /// } +>>>>>>> 4e0490363 (rename to plural form) +======= + /// # use std::marker::PhantomData; + /// struct S { + /// _marker: PhantomData + /// } + /// + /// let _: S = S { + /// _marker: PhantomData + /// }; +>>>>>>> 48ae5a071 (fix lint docs) + /// ``` + #[clippy::version = "1.71.0"] + pub DEFAULT_CONSTRUCTED_UNIT_STRUCTS, + complexity, + "unit structs can be contructed without calling `default`" +} +declare_lint_pass!(DefaultConstructedUnitStructs => [DEFAULT_CONSTRUCTED_UNIT_STRUCTS]); + +<<<<<<< HEAD +fn is_alias(ty: hir::Ty<'_>) -> bool { + if let hir::TyKind::Path(ref qpath) = ty.kind { + is_ty_alias(qpath) + } else { + false + } +} + +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +impl LateLintPass<'_> for DefaultConstructedUnitStructs { + fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + if_chain!( + // make sure we have a call to `Default::default` + if let hir::ExprKind::Call(fn_expr, &[]) = expr.kind; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if let ExprKind::Path(ref qpath@ hir::QPath::TypeRelative(_,_)) = fn_expr.kind; +======= + if let ExprKind::Path(ref qpath) = fn_expr.kind; +>>>>>>> 4e0490363 (rename to plural form) +======= + if let ExprKind::Path(ref qpath@ hir::QPath::TypeRelative(_,_)) = fn_expr.kind; +>>>>>>> 870100986 (add more test cases) +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) + if let ExprKind::Path(ref qpath @ hir::QPath::TypeRelative(base, _)) = fn_expr.kind; + // make sure this isn't a type alias: + // `::Assoc` cannot be used as a constructor + if !is_alias(*base); +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= + if let ExprKind::Path(ref qpath@ hir::QPath::TypeRelative(_,_)) = fn_expr.kind; +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + if let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id); + if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD); + // make sure we have a struct with no fields (unit struct) + if let ty::Adt(def, ..) = cx.typeck_results().expr_ty(expr).kind(); +<<<<<<< HEAD +<<<<<<< HEAD + if def.is_struct(); + if let var @ ty::VariantDef { ctor: Some((hir::def::CtorKind::Const, _)), .. } = def.non_enum_variant(); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if !var.is_field_list_non_exhaustive(); + if !expr.span.from_expansion() && !qpath.span().from_expansion(); +======= +<<<<<<< HEAD + if def.is_struct() && def.is_payloadfree() + && !def.non_enum_variant().is_field_list_non_exhaustive() + && !is_from_proc_macro(cx, expr); +>>>>>>> 4e0490363 (rename to plural form) +======= + if def.is_struct(); + if let var @ ty::VariantDef { ctor: Some((hir::def::CtorKind::Const, _)), .. } = def.non_enum_variant(); +<<<<<<< HEAD + if !var.is_field_list_non_exhaustive() && !is_from_proc_macro(cx, expr); +>>>>>>> 870100986 (add more test cases) +======= + if !var.is_field_list_non_exhaustive(); + if !expr.span.from_expansion() && !qpath.span().from_expansion(); +>>>>>>> 68eb864c9 (Ignore expressions from macros in default_constructed_unit_structs) +======= + if !var.is_field_list_non_exhaustive() && !is_from_proc_macro(cx, expr); +>>>>>>> 7e9abb311 (Merge commit '371120bdbf58a331db5dcfb2d9cddc040f486de8' into clippyup) +======= + if !var.is_field_list_non_exhaustive(); + if !expr.span.from_expansion() && !qpath.span().from_expansion(); +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= + if !var.is_field_list_non_exhaustive(); + if !expr.span.from_expansion() && !qpath.span().from_expansion(); +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + then { + span_lint_and_sugg( + cx, + DEFAULT_CONSTRUCTED_UNIT_STRUCTS, + expr.span.with_lo(qpath.qself_span().hi()), + "use of `default` to create a unit struct", + "remove this call to `default`", + String::new(), + Applicability::MachineApplicable, + ) + } + ); + } +} diff --git a/clippy_lints/src/default_instead_of_iter_empty.rs b/clippy_lints/src/default_instead_of_iter_empty.rs index f296b80d283d..572990aaba10 100644 --- a/clippy_lints/src/default_instead_of_iter_empty.rs +++ b/clippy_lints/src/default_instead_of_iter_empty.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::last_path_segment; use clippy_utils::source::snippet_with_context; -use clippy_utils::{match_def_path, paths}; +use clippy_utils::{last_path_segment, match_def_path, paths}; use rustc_errors::Applicability; use rustc_hir::{def, Expr, ExprKind, GenericArg, QPath, TyKind}; use rustc_lint::{LateContext, LateLintPass}; diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs index 4e1a6cd4d735..0708b1cabdb5 100644 --- a/clippy_lints/src/default_numeric_fallback.rs +++ b/clippy_lints/src/default_numeric_fallback.rs @@ -4,15 +4,11 @@ use clippy_utils::{get_parent_node, numeric_literal}; use if_chain::if_chain; use rustc_ast::ast::{LitFloatType, LitIntType, LitKind}; use rustc_errors::Applicability; -use rustc_hir::{ - intravisit::{walk_expr, walk_stmt, Visitor}, - Body, Expr, ExprKind, HirId, ItemKind, Lit, Node, Stmt, StmtKind, -}; +use rustc_hir::intravisit::{walk_expr, walk_stmt, Visitor}; +use rustc_hir::{Body, Expr, ExprKind, HirId, ItemKind, Lit, Node, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::{ - lint::in_external_macro, - ty::{self, FloatTy, IntTy, PolyFnSig, Ty}, -}; +use rustc_middle::lint::in_external_macro; +use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use std::iter; @@ -161,7 +157,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> { let fields_def = &variant.fields; // Push field type then visit each field expr. - for field in fields.iter() { + for field in *fields { let bound = fields_def .iter() diff --git a/clippy_lints/src/default_union_representation.rs b/clippy_lints/src/default_union_representation.rs index dec357ab75c3..03b5a2d6d082 100644 --- a/clippy_lints/src/default_union_representation.rs +++ b/clippy_lints/src/default_union_representation.rs @@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation { None, &format!( "consider annotating `{}` with `#[repr(C)]` to explicitly specify memory layout", - cx.tcx.def_path_str(item.owner_id.to_def_id()) + cx.tcx.def_path_str(item.owner_id) ), ); } diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 7f3f26bed7c7..def648a3b693 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -12,12 +12,11 @@ use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::graph::iterate::{CycleDetector, TriColorDepthFirstSearch}; use rustc_errors::Applicability; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{walk_ty, Visitor}; use rustc_hir::{ - self as hir, - def_id::{DefId, LocalDefId}, - BindingAnnotation, Body, BodyId, BorrowKind, Closure, Expr, ExprKind, FnRetTy, GenericArg, HirId, ImplItem, - ImplItemKind, Item, ItemKind, Local, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TraitItem, + self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Closure, Expr, ExprKind, FnRetTy, GenericArg, HirId, + ImplItem, ImplItemKind, Item, ItemKind, Local, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TraitItem, TraitItemKind, TyKind, UnOp, }; use rustc_index::bit_set::BitSet; @@ -26,13 +25,15 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::{Rvalue, StatementKind}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{ - self, Binder, BoundVariableKind, Clause, EarlyBinder, FnSig, GenericArgKind, List, ParamEnv, ParamTy, - PredicateKind, ProjectionPredicate, Ty, TyCtxt, TypeVisitableExt, TypeckResults, + self, Binder, BoundVariableKind, ClauseKind, EarlyBinder, FnSig, GenericArgKind, List, ParamEnv, ParamTy, + ProjectionPredicate, Ty, TyCtxt, TypeVisitableExt, TypeckResults, }; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{symbol::sym, Span, Symbol}; +use rustc_span::symbol::sym; +use rustc_span::{Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt as _; -use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause}; +use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; +use rustc_trait_selection::traits::{Obligation, ObligationCause}; use std::collections::VecDeque; declare_clippy_lint! { @@ -56,9 +57,11 @@ declare_clippy_lint! { /// let b = &*a; /// ``` /// - /// This lint excludes: + /// This lint excludes all of: /// ```rust,ignore /// let _ = d.unwrap().deref(); + /// let _ = Foo::deref(&foo); + /// let _ = ::deref(&foo); /// ``` #[clippy::version = "1.44.0"] pub EXPLICIT_DEREF_METHODS, @@ -75,6 +78,11 @@ declare_clippy_lint! { /// Suggests that the receiver of the expression borrows /// the expression. /// + /// ### Known problems + /// The lint cannot tell when the implementation of a trait + /// for `&T` and `T` do different things. Removing a borrow + /// in such a case can change the semantics of the code. + /// /// ### Example /// ```rust /// fn fun(_a: &i32) {} @@ -355,15 +363,17 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { // start auto-deref. // 4. If the chain of non-user-defined derefs ends with a mutable re-borrow, and re-borrow // adjustments will not be inserted automatically, then leave one further reference to avoid - // moving a mutable borrow. - // e.g. - // fn foo(x: &mut Option<&mut T>, y: &mut T) { - // let x = match x { - // // Removing the borrow will cause `x` to be moved - // Some(x) => &mut *x, - // None => y - // }; - // } + // moving a mutable borrow. e.g. + // + // ```rust + // fn foo(x: &mut Option<&mut T>, y: &mut T) { + // let x = match x { + // // Removing the borrow will cause `x` to be moved + // Some(x) => &mut *x, + // None => y + // }; + // } + // ``` let deref_msg = "this expression creates a reference which is immediately dereferenced by the compiler"; let borrow_msg = "this expression borrows a value the compiler would automatically borrow"; @@ -585,7 +595,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { pat.spans, "this pattern creates a reference to a reference", |diag| { - diag.multipart_suggestion("try this", replacements, app); + diag.multipart_suggestion("try", replacements, app); }, ); } @@ -1133,7 +1143,7 @@ fn needless_borrow_impl_arg_position<'tcx>( let projection_predicates = predicates .iter() .filter_map(|predicate| { - if let PredicateKind::Clause(Clause::Projection(projection_predicate)) = predicate.kind().skip_binder() { + if let ClauseKind::Projection(projection_predicate) = predicate.kind().skip_binder() { Some(projection_predicate) } else { None @@ -1147,7 +1157,7 @@ fn needless_borrow_impl_arg_position<'tcx>( if predicates .iter() .filter_map(|predicate| { - if let PredicateKind::Clause(Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() + if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() && trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx) { Some(trait_predicate.trait_ref.def_id) @@ -1209,7 +1219,7 @@ fn needless_borrow_impl_arg_position<'tcx>( } predicates.iter().all(|predicate| { - if let PredicateKind::Clause(Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() + if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() && cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id) && let ty::Param(param_ty) = trait_predicate.self_ty().kind() && let GenericArgKind::Type(ty) = substs_with_referent_ty[param_ty.index as usize].unpack() @@ -1219,7 +1229,7 @@ fn needless_borrow_impl_arg_position<'tcx>( return false; } - let predicate = EarlyBinder(predicate).subst(cx.tcx, &substs_with_referent_ty); + let predicate = EarlyBinder::bind(predicate).subst(cx.tcx, &substs_with_referent_ty); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); let infcx = cx.tcx.infer_ctxt().build(); infcx.predicate_must_hold_modulo_regions(&obligation) @@ -1292,8 +1302,8 @@ fn referent_used_exactly_once<'tcx>( possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>, reference: &Expr<'tcx>, ) -> bool { - let mir = enclosing_mir(cx.tcx, reference.hir_id); - if let Some(local) = expr_local(cx.tcx, reference) + if let Some(mir) = enclosing_mir(cx.tcx, reference.hir_id) + && let Some(local) = expr_local(cx.tcx, reference) && let [location] = *local_assignments(mir, local).as_slice() && let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index) && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind @@ -1424,6 +1434,8 @@ fn ty_auto_deref_stability<'tcx>( continue; }, ty::Param(_) => TyPosition::new_deref_stable_for_result(precedence, ty), + ty::Alias(ty::Weak, _) => unreachable!("should have been normalized away above"), + ty::Alias(ty::Inherent, _) => unreachable!("inherent projection should have been normalized away above"), ty::Alias(ty::Projection, _) if ty.has_non_region_param() => { TyPosition::new_deref_stable_for_result(precedence, ty) }, @@ -1479,7 +1491,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data target_mut, } => { let mut app = Applicability::MachineApplicable; - let (expr_str, expr_is_macro_call) = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app); + let (expr_str, _expr_is_macro_call) = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app); let ty = cx.typeck_results().expr_ty(expr); let (_, ref_count) = peel_mid_ty_refs(ty); let deref_str = if ty_changed_count >= ref_count && ref_count != 0 { @@ -1502,11 +1514,39 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data "&" }; - let expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence().order() < PREC_PREFIX { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> eed466281 (ignore `Foo::deref` altogether) + // expr_str (the suggestion) is never shown if is_final_ufcs is true, since it's + // `expr.kind == ExprKind::Call`. Therefore, this is, afaik, always unnecessary. + /* + expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence().order() < PREC_PREFIX { + Cow::Owned(format!("({expr_str})")) +<<<<<<< HEAD +======= + let mut expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence().order() < PREC_PREFIX { format!("({expr_str})") +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= +>>>>>>> eed466281 (ignore `Foo::deref` altogether) } else { - expr_str.into_owned() + expr_str }; + */ +<<<<<<< HEAD + + // Fix #10850, do not lint if it's `Foo::deref` instead of `foo.deref()`. + if is_final_ufcs { + return; + } +======= +>>>>>>> eed466281 (ignore `Foo::deref` altogether) + + // Fix #10850, do not lint if it's `Foo::deref` instead of `foo.deref()`. + if is_final_ufcs { + return; + } span_lint_and_sugg( cx, @@ -1516,7 +1556,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data Mutability::Not => "explicit `deref` method call", Mutability::Mut => "explicit `deref_mut` method call", }, - "try this", + "try", format!("{addr_of_str}{deref_str}{expr_str}"), app, ); @@ -1578,7 +1618,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data } else { format!("{prefix}{snip}") }; - diag.span_suggestion(data.span, "try this", sugg, app); + diag.span_suggestion(data.span, "try", sugg, app); }, ); }, @@ -1605,7 +1645,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data |diag| { let mut app = Applicability::MachineApplicable; let snip = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app).0; - diag.span_suggestion(data.span, "try this", snip.into_owned(), app); + diag.span_suggestion(data.span, "try", snip.into_owned(), app); }, ); }, diff --git a/clippy_lints/src/derivable_impls.rs b/clippy_lints/src/derivable_impls.rs index 8f68f90a2a13..ffd362356266 100644 --- a/clippy_lints/src/derivable_impls.rs +++ b/clippy_lints/src/derivable_impls.rs @@ -3,12 +3,22 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::indent_of; use clippy_utils::{is_default_equivalent, peel_blocks}; use rustc_errors::Applicability; +use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::{ - def::{CtorKind, CtorOf, DefKind, Res}, - Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, Ty, TyKind, + self as hir, Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{Adt, AdtDef, SubstsRef}; +<<<<<<< HEAD +use rustc_middle::ty::adjustment::{Adjust, PointerCoercion}; +use rustc_middle::ty::{self, Adt, AdtDef, SubstsRef, Ty, TypeckResults}; +======= +use rustc_middle::ty::adjustment::{Adjust, PointerCast}; +<<<<<<< HEAD +use rustc_middle::ty::{self, Adt, AdtDef, SubstsRef, TypeckResults}; +>>>>>>> 2ba192695 ([`derivable_impls`]: don't lint if expr unsize-coerces) +======= +use rustc_middle::ty::{self, Adt, AdtDef, SubstsRef, Ty, TypeckResults}; +>>>>>>> 4795c9193 (fix internal lints) use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::sym; @@ -75,13 +85,43 @@ fn is_path_self(e: &Expr<'_>) -> bool { } } +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +fn contains_trait_object(ty: Ty<'_>) -> bool { + match ty.kind() { + ty::Ref(_, ty, _) => contains_trait_object(*ty), + ty::Adt(def, substs) => def.is_box() && substs[0].as_type().map_or(false, contains_trait_object), + ty::Dynamic(..) => true, +======= +fn contains_trait_object(cx: &LateContext<'_>, ty: ty::Ty<'_>) -> bool { +======= +fn contains_trait_object(ty: ty::Ty<'_>) -> bool { +>>>>>>> fcb9a382f (dogfood) + match ty.kind() { + ty::TyKind::Ref(_, ty, _) => contains_trait_object(*ty), + ty::TyKind::Adt(def, substs) => def.is_box() && substs[0].as_type().map_or(false, contains_trait_object), + ty::TyKind::Dynamic(..) => true, +>>>>>>> 2ba192695 ([`derivable_impls`]: don't lint if expr unsize-coerces) +======= +fn contains_trait_object(ty: Ty<'_>) -> bool { + match ty.kind() { + ty::Ref(_, ty, _) => contains_trait_object(*ty), + ty::Adt(def, substs) => def.is_box() && substs[0].as_type().map_or(false, contains_trait_object), + ty::Dynamic(..) => true, +>>>>>>> 4795c9193 (fix internal lints) + _ => false, + } +} + fn check_struct<'tcx>( cx: &LateContext<'tcx>, item: &'tcx Item<'_>, - self_ty: &Ty<'_>, + self_ty: &hir::Ty<'_>, func_expr: &Expr<'_>, adt_def: AdtDef<'_>, substs: SubstsRef<'_>, + typeck_results: &'tcx TypeckResults<'tcx>, ) { if let TyKind::Path(QPath::Resolved(_, p)) = self_ty.kind { if let Some(PathSegment { args, .. }) = p.segments.last() { @@ -96,10 +136,46 @@ fn check_struct<'tcx>( } } } + + // the default() call might unsize coerce to a trait object (e.g. Box to Box), + // which would not be the same if derived (see #10158). + // this closure checks both if the expr is equivalent to a `default()` call and does not + // have such coercions. + let is_default_without_adjusts = |expr| { + is_default_equivalent(cx, expr) + && typeck_results.expr_adjustments(expr).iter().all(|adj| { +<<<<<<< HEAD +<<<<<<< HEAD + !matches!(adj.kind, Adjust::Pointer(PointerCoercion::Unsize) + if contains_trait_object(adj.target)) +======= + !matches!(adj.kind, Adjust::Pointer(PointerCast::Unsize) +======= + !matches!(adj.kind, Adjust::Pointer(PointerCast::Unsize) +<<<<<<< HEAD +>>>>>>> 5b6ba204a (fmt) + if contains_trait_object(cx, adj.target)) +>>>>>>> 2ba192695 ([`derivable_impls`]: don't lint if expr unsize-coerces) +======= + if contains_trait_object(adj.target)) +>>>>>>> fcb9a382f (dogfood) + }) + }; + let should_emit = match peel_blocks(func_expr).kind { - ExprKind::Tup(fields) => fields.iter().all(|e| is_default_equivalent(cx, e)), - ExprKind::Call(callee, args) if is_path_self(callee) => args.iter().all(|e| is_default_equivalent(cx, e)), - ExprKind::Struct(_, fields, _) => fields.iter().all(|ef| is_default_equivalent(cx, ef.expr)), +<<<<<<< HEAD +<<<<<<< HEAD + ExprKind::Tup(fields) => fields.iter().all(is_default_without_adjusts), + ExprKind::Call(callee, args) if is_path_self(callee) => args.iter().all(is_default_without_adjusts), +======= + ExprKind::Tup(fields) => fields.iter().all(|e| is_default_without_adjusts(e)), + ExprKind::Call(callee, args) if is_path_self(callee) => args.iter().all(|e| is_default_without_adjusts(e)), +>>>>>>> 2ba192695 ([`derivable_impls`]: don't lint if expr unsize-coerces) +======= + ExprKind::Tup(fields) => fields.iter().all(is_default_without_adjusts), + ExprKind::Call(callee, args) if is_path_self(callee) => args.iter().all(is_default_without_adjusts), +>>>>>>> fcb9a382f (dogfood) + ExprKind::Struct(_, fields, _) => fields.iter().all(|ef| is_default_without_adjusts(ef.expr)), _ => false, }; @@ -197,7 +273,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { then { if adt_def.is_struct() { - check_struct(cx, item, self_ty, func_expr, adt_def, substs); + check_struct(cx, item, self_ty, func_expr, adt_def, substs, cx.tcx.typeck_body(*b)); } else if adt_def.is_enum() && self.msrv.meets(msrvs::DEFAULT_ENUM_ATTRIBUTE) { check_enum(cx, item, func_expr, adt_def); } diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index f425dd5fb70b..ff0537fefda2 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::paths; use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy}; -use clippy_utils::{is_lint_allowed, match_def_path}; +use clippy_utils::{is_lint_allowed, match_def_path, paths}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; @@ -14,7 +13,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::traits::Reveal; use rustc_middle::ty::{ - self, Binder, BoundConstness, Clause, GenericArgKind, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, + self, BoundConstness, ClauseKind, GenericArgKind, GenericParamDefKind, ImplPolarity, ParamEnv, ToPredicate, TraitPredicate, Ty, TyCtxt, }; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -503,7 +502,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> let ty_predicates = tcx.predicates_of(did).predicates; for (p, _) in ty_predicates { - if let PredicateKind::Clause(Clause::Trait(p)) = p.kind().skip_binder() + if let ClauseKind::Trait(p) = p.kind().skip_binder() && p.trait_ref.def_id == eq_trait_id && let ty::Param(self_ty) = p.trait_ref.self_ty().kind() && p.constness == BoundConstness::NotConst @@ -514,13 +513,18 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> } ParamEnv::new( - tcx.mk_predicates_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( + tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { +<<<<<<< HEAD + ClauseKind::Trait(TraitPredicate { +======= tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait(TraitPredicate { - trait_ref: tcx.mk_trait_ref(eq_trait_id, [tcx.mk_param_from_def(param)]), +>>>>>>> e4f5d83fa (Fixed formatting.) + trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]), constness: BoundConstness::NotConst, polarity: ImplPolarity::Positive, - })))) + }) + .to_predicate(tcx) }), )), Reveal::UserFacing, diff --git a/clippy_lints/src/disallowed_names.rs b/clippy_lints/src/disallowed_names.rs index 6e6615f08ee7..04c2d44137a3 100644 --- a/clippy_lints/src/disallowed_names.rs +++ b/clippy_lints/src/disallowed_names.rs @@ -1,4 +1,5 @@ -use clippy_utils::{diagnostics::span_lint, is_test_module_or_function}; +use clippy_utils::diagnostics::span_lint; +use clippy_utils::is_test_module_or_function; use rustc_data_structures::fx::FxHashSet; use rustc_hir::{Item, Pat, PatKind}; use rustc_lint::{LateContext, LateLintPass}; diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index 384aca7feadd..2f40477e76b3 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -31,9 +31,8 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::edition::Edition; use rustc_span::source_map::{BytePos, FilePathMapping, SourceMap, Span}; use rustc_span::{sym, FileName, Pos}; -use std::io; use std::ops::Range; -use std::thread; +use std::{io, thread}; use url::Url; declare_clippy_lint! { @@ -571,6 +570,7 @@ fn check_doc<'a, Events: Iterator, Range, Span)> = Vec::new(); @@ -584,6 +584,8 @@ fn check_doc<'a, Events: Iterator, Range, Range Visitor<'tcx> for FindPanicUnwrap<'a, 'tcx> { if is_panic(self.cx, macro_call.def_id) || matches!( self.cx.tcx.item_name(macro_call.def_id).as_str(), - "assert" | "assert_eq" | "assert_ne" | "todo" + "assert" | "assert_eq" | "assert_ne" ) { self.panic_span = Some(macro_call.span); } } - // check for `unwrap` - if let Some(arglists) = method_chain_args(expr, &["unwrap"]) { +<<<<<<< HEAD +<<<<<<< HEAD + // check for `unwrap` and `expect` for both `Option` and `Result` +======= + // check for `unwrap` and `expect` both `Option` and `Result` +>>>>>>> 79f93a655 (missing_panics_doc: pickup expect method) +======= + // check for `unwrap` and `expect` for both `Option` and `Result` +>>>>>>> 73c0c1452 (improve grammer in comment sentence) + if let Some(arglists) = method_chain_args(expr, &["unwrap"]).or(method_chain_args(expr, &["expect"])) { let receiver_ty = self.typeck_results.expr_ty(arglists[0].0).peel_refs(); if is_type_diagnostic_item(self.cx, receiver_ty, sym::Option) || is_type_diagnostic_item(self.cx, receiver_ty, sym::Result) diff --git a/clippy_lints/src/drop_forget_ref.rs b/clippy_lints/src/drop_forget_ref.rs index 11e1bcdf12d1..e646c30757f8 100644 --- a/clippy_lints/src/drop_forget_ref.rs +++ b/clippy_lints/src/drop_forget_ref.rs @@ -1,107 +1,11 @@ -use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note}; -use clippy_utils::get_parent_node; -use clippy_utils::is_must_use_func_call; +use clippy_utils::diagnostics::span_lint_and_note; use clippy_utils::ty::{is_copy, is_must_use_ty, is_type_lang_item}; +use clippy_utils::{get_parent_node, is_must_use_func_call}; use rustc_hir::{Arm, Expr, ExprKind, LangItem, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; - -declare_clippy_lint! { - /// ### What it does - /// Checks for calls to `std::mem::drop` with a reference - /// instead of an owned value. - /// - /// ### Why is this bad? - /// Calling `drop` on a reference will only drop the - /// reference itself, which is a no-op. It will not call the `drop` method (from - /// the `Drop` trait implementation) on the underlying referenced value, which - /// is likely what was intended. - /// - /// ### Example - /// ```ignore - /// let mut lock_guard = mutex.lock(); - /// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex - /// // still locked - /// operation_that_requires_mutex_to_be_unlocked(); - /// ``` - #[clippy::version = "pre 1.29.0"] - pub DROP_REF, - correctness, - "calls to `std::mem::drop` with a reference instead of an owned value" -} - -declare_clippy_lint! { - /// ### What it does - /// Checks for calls to `std::mem::forget` with a reference - /// instead of an owned value. - /// - /// ### Why is this bad? - /// Calling `forget` on a reference will only forget the - /// reference itself, which is a no-op. It will not forget the underlying - /// referenced - /// value, which is likely what was intended. - /// - /// ### Example - /// ```rust - /// let x = Box::new(1); - /// std::mem::forget(&x) // Should have been forget(x), x will still be dropped - /// ``` - #[clippy::version = "pre 1.29.0"] - pub FORGET_REF, - correctness, - "calls to `std::mem::forget` with a reference instead of an owned value" -} - -declare_clippy_lint! { - /// ### What it does - /// Checks for calls to `std::mem::drop` with a value - /// that derives the Copy trait - /// - /// ### Why is this bad? - /// Calling `std::mem::drop` [does nothing for types that - /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the - /// value will be copied and moved into the function on invocation. - /// - /// ### Example - /// ```rust - /// let x: i32 = 42; // i32 implements Copy - /// std::mem::drop(x) // A copy of x is passed to the function, leaving the - /// // original unaffected - /// ``` - #[clippy::version = "pre 1.29.0"] - pub DROP_COPY, - correctness, - "calls to `std::mem::drop` with a value that implements Copy" -} - -declare_clippy_lint! { - /// ### What it does - /// Checks for calls to `std::mem::forget` with a value that - /// derives the Copy trait - /// - /// ### Why is this bad? - /// Calling `std::mem::forget` [does nothing for types that - /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the - /// value will be copied and moved into the function on invocation. - /// - /// An alternative, but also valid, explanation is that Copy types do not - /// implement - /// the Drop trait, which means they have no destructors. Without a destructor, - /// there - /// is nothing for `std::mem::forget` to ignore. - /// - /// ### Example - /// ```rust - /// let x: i32 = 42; // i32 implements Copy - /// std::mem::forget(x) // A copy of x is passed to the function, leaving the - /// // original unaffected - /// ``` - #[clippy::version = "pre 1.29.0"] - pub FORGET_COPY, - correctness, - "calls to `std::mem::forget` with a value that implements Copy" -} +use std::borrow::Cow; declare_clippy_lint! { /// ### What it does @@ -145,54 +49,59 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Prevents the safe `std::mem::drop` function from being called on `std::mem::ManuallyDrop`. + /// Checks for usage of `std::mem::forget(t)` where `t` is + /// `Drop` or has a field that implements `Drop`. /// /// ### Why is this bad? - /// The safe `drop` function does not drop the inner value of a `ManuallyDrop`. - /// - /// ### Known problems - /// Does not catch cases if the user binds `std::mem::drop` - /// to a different name and calls it that way. + /// `std::mem::forget(t)` prevents `t` from running its + /// destructor, possibly causing leaks. /// /// ### Example /// ```rust - /// struct S; - /// drop(std::mem::ManuallyDrop::new(S)); + /// # use std::mem; + /// # use std::rc::Rc; + /// mem::forget(Rc::new(55)) /// ``` - /// Use instead: + #[clippy::version = "pre 1.29.0"] + pub MEM_FORGET, + restriction, + "`mem::forget` usage on `Drop` types, likely to cause memory leaks" +} + +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of `std::mem::forget(t)` where `t` is + /// `Drop` or has a field that implements `Drop`. + /// + /// ### Why is this bad? + /// `std::mem::forget(t)` prevents `t` from running its + /// destructor, possibly causing leaks. + /// + /// ### Example /// ```rust - /// struct S; - /// unsafe { - /// std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S)); - /// } + /// # use std::mem; + /// # use std::rc::Rc; + /// mem::forget(Rc::new(55)) /// ``` - #[clippy::version = "1.49.0"] - pub UNDROPPED_MANUALLY_DROPS, - correctness, - "use of safe `std::mem::drop` function to drop a std::mem::ManuallyDrop, which will not drop the inner value" + #[clippy::version = "pre 1.29.0"] + pub MEM_FORGET, + restriction, + "`mem::forget` usage on `Drop` types, likely to cause memory leaks" } -const DROP_REF_SUMMARY: &str = "calls to `std::mem::drop` with a reference instead of an owned value. \ - Dropping a reference does nothing"; -const FORGET_REF_SUMMARY: &str = "calls to `std::mem::forget` with a reference instead of an owned value. \ - Forgetting a reference does nothing"; -const DROP_COPY_SUMMARY: &str = "calls to `std::mem::drop` with a value that implements `Copy`. \ - Dropping a copy leaves the original intact"; -const FORGET_COPY_SUMMARY: &str = "calls to `std::mem::forget` with a value that implements `Copy`. \ - Forgetting a copy leaves the original intact"; const DROP_NON_DROP_SUMMARY: &str = "call to `std::mem::drop` with a value that does not implement `Drop`. \ Dropping such a type only extends its contained lifetimes"; const FORGET_NON_DROP_SUMMARY: &str = "call to `std::mem::forget` with a value that does not implement `Drop`. \ Forgetting such a type is the same as dropping it"; declare_lint_pass!(DropForgetRef => [ - DROP_REF, - FORGET_REF, - DROP_COPY, - FORGET_COPY, DROP_NON_DROP, FORGET_NON_DROP, - UNDROPPED_MANUALLY_DROPS +<<<<<<< HEAD +======= + UNDROPPED_MANUALLY_DROPS, +>>>>>>> b6f194b48 (move to `drop_forget_ref`) + MEM_FORGET, ]); impl<'tcx> LateLintPass<'tcx> for DropForgetRef { @@ -205,22 +114,13 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { let arg_ty = cx.typeck_results().expr_ty(arg); let is_copy = is_copy(cx, arg_ty); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); - let (lint, msg) = match fn_name { - sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => (DROP_REF, DROP_REF_SUMMARY), - sym::mem_forget if arg_ty.is_ref() => (FORGET_REF, FORGET_REF_SUMMARY), - sym::mem_drop if is_copy && !drop_is_single_call_in_arm => (DROP_COPY, DROP_COPY_SUMMARY), - sym::mem_forget if is_copy => (FORGET_COPY, FORGET_COPY_SUMMARY), - sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => { - span_lint_and_help( - cx, - UNDROPPED_MANUALLY_DROPS, - expr.span, - "the inner value of this ManuallyDrop will not be dropped", - None, - "to drop a `ManuallyDrop`, use std::mem::ManuallyDrop::drop", - ); - return; - } + let (lint, msg, note_span) = match fn_name { + // early return for uplifted lints: dropping_references, dropping_copy_types, forgetting_references, forgetting_copy_types + sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return, + sym::mem_forget if arg_ty.is_ref() => return, + sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return, + sym::mem_forget if is_copy => return, + sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => return, sym::mem_drop if !(arg_ty.needs_drop(cx.tcx, cx.param_env) || is_must_use_func_call(cx, arg) @@ -228,19 +128,71 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { || drop_is_single_call_in_arm ) => { - (DROP_NON_DROP, DROP_NON_DROP_SUMMARY) +<<<<<<< HEAD +<<<<<<< HEAD + (DROP_NON_DROP, DROP_NON_DROP_SUMMARY.into(), Some(arg.span)) }, - sym::mem_forget if !arg_ty.needs_drop(cx.tcx, cx.param_env) => { - (FORGET_NON_DROP, FORGET_NON_DROP_SUMMARY) + sym::mem_forget => { + if arg_ty.needs_drop(cx.tcx, cx.param_env) { + ( + MEM_FORGET, + Cow::Owned(format!( + "usage of `mem::forget` on {}", + if arg_ty.ty_adt_def().map_or(false, |def| def.has_dtor(cx.tcx)) { + "`Drop` type" + } else { + "type with `Drop` fields" + } + )), + None, + ) + } else { + (FORGET_NON_DROP, FORGET_NON_DROP_SUMMARY.into(), Some(arg.span)) +======= + (DROP_NON_DROP, DROP_NON_DROP_SUMMARY.into()) +======= + (DROP_NON_DROP, DROP_NON_DROP_SUMMARY.into(), Some(arg.span)) +>>>>>>> a5ae9044f (make note less verbose) }, + sym::mem_forget => { + if arg_ty.needs_drop(cx.tcx, cx.param_env) { + ( + MEM_FORGET, + Cow::Owned(format!( + "usage of `mem::forget` on {}", + if arg_ty.ty_adt_def().map_or(false, |def| def.has_dtor(cx.tcx)) { + "`Drop` type" + } else { + "type with `Drop` fields" + } + )), + None, + ) + } else { +<<<<<<< HEAD + (FORGET_NON_DROP, FORGET_NON_DROP_SUMMARY.into()) +>>>>>>> b6f194b48 (move to `drop_forget_ref`) +======= + (FORGET_NON_DROP, FORGET_NON_DROP_SUMMARY.into(), Some(arg.span)) +>>>>>>> a5ae9044f (make note less verbose) + } + } _ => return, }; span_lint_and_note( cx, lint, expr.span, - msg, + &msg, +<<<<<<< HEAD +<<<<<<< HEAD + note_span, +======= Some(arg.span), +>>>>>>> b6f194b48 (move to `drop_forget_ref`) +======= + note_span, +>>>>>>> a5ae9044f (make note less verbose) &format!("argument has type `{arg_ty}`"), ); } diff --git a/clippy_lints/src/empty_drop.rs b/clippy_lints/src/empty_drop.rs index ec063c0f777e..209fb66fa40f 100644 --- a/clippy_lints/src/empty_drop.rs +++ b/clippy_lints/src/empty_drop.rs @@ -1,4 +1,5 @@ -use clippy_utils::{diagnostics::span_lint_and_sugg, peel_blocks}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::peel_blocks; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Body, ExprKind, Impl, ImplItemKind, Item, ItemKind, Node}; diff --git a/clippy_lints/src/empty_structs_with_brackets.rs b/clippy_lints/src/empty_structs_with_brackets.rs index c3a020433de8..282157181abb 100644 --- a/clippy_lints/src/empty_structs_with_brackets.rs +++ b/clippy_lints/src/empty_structs_with_brackets.rs @@ -1,4 +1,5 @@ -use clippy_utils::{diagnostics::span_lint_and_then, source::snippet_opt}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::source::snippet_opt; use rustc_ast::ast::{Item, ItemKind, VariantData}; use rustc_errors::Applicability; use rustc_lexer::TokenKind; diff --git a/clippy_lints/src/endian_bytes.rs b/clippy_lints/src/endian_bytes.rs new file mode 100644 index 000000000000..048d845236d0 --- /dev/null +++ b/clippy_lints/src/endian_bytes.rs @@ -0,0 +1,562 @@ +<<<<<<< HEAD +<<<<<<< HEAD +use crate::Lint; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::is_lint_allowed; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +<<<<<<< HEAD +use rustc_middle::{lint::in_external_macro, ty::Ty}; +<<<<<<< HEAD +======= +use rustc_middle::lint::in_external_macro; +use rustc_middle::ty::Ty; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::Symbol; +use std::borrow::Cow; + +declare_clippy_lint! { + /// ### What it does + /// Checks for the usage of the `to_ne_bytes` method and/or the function `from_ne_bytes`. +======= +use clippy_utils::{ + diagnostics::{span_lint_and_help, span_lint_and_then}, + is_lint_allowed, match_def_path, path_def_id, +}; +======= +use crate::Lint; +use clippy_utils::{diagnostics::span_lint_and_then, is_lint_allowed}; +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +======= +>>>>>>> 04b7cae37 (refine output) +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::Symbol; +use std::borrow::Cow; + +declare_clippy_lint! { + /// ### What it does +<<<<<<< HEAD + /// Checks for the usage of the `to_ne_bytes` method. +>>>>>>> 3ab6aeefb (`to_xx_bytes` implemented, `from_xx_bytes` todo) +======= + /// Checks for the usage of the `to_ne_bytes` method and/or the function `from_ne_bytes`. +>>>>>>> 95e8c0b35 (don't allocate the names) + /// + /// ### Why is this bad? + /// It's not, but some may prefer to specify the target endianness explicitly. + /// + /// ### Example + /// ```rust,ignore + /// let _x = 2i32.to_ne_bytes(); + /// let _y = 2i64.to_ne_bytes(); + /// ``` + #[clippy::version = "1.71.0"] +<<<<<<< HEAD +<<<<<<< HEAD + pub HOST_ENDIAN_BYTES, + restriction, + "disallows usage of the `to_ne_bytes` method" +} + +declare_clippy_lint! { + /// ### What it does + /// Checks for the usage of the `to_le_bytes` method and/or the function `from_le_bytes`. +<<<<<<< HEAD + /// + /// ### Why is this bad? + /// It's not, but some may wish to lint usage of this method, either to suggest using the host + /// endianness or big endian. + /// + /// ### Example + /// ```rust,ignore + /// let _x = 2i32.to_le_bytes(); + /// let _y = 2i64.to_le_bytes(); + /// ``` + #[clippy::version = "1.71.0"] +======= +>>>>>>> 3ab6aeefb (`to_xx_bytes` implemented, `from_xx_bytes` todo) + pub LITTLE_ENDIAN_BYTES, +======= + pub HOST_ENDIAN_BYTES, +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) + restriction, + "disallows usage of the `to_ne_bytes` method" +} + +declare_clippy_lint! { + /// ### What it does +<<<<<<< HEAD + /// Checks for the usage of the `to_be_bytes` method and/or the function `from_be_bytes`. + /// + /// ### Why is this bad? + /// It's not, but some may wish to lint usage of this method, either to suggest using the host + /// endianness or little endian. + /// + /// ### Example + /// ```rust,ignore + /// let _x = 2i32.to_be_bytes(); + /// let _y = 2i64.to_be_bytes(); +======= + /// Checks for the usage of the `to_le_bytes` method. +======= +>>>>>>> 95e8c0b35 (don't allocate the names) + /// + /// ### Why is this bad? + /// It's not, but some may wish to lint usage of this method, either to suggest using the host + /// endianness or big endian. + /// + /// ### Example + /// ```rust,ignore +<<<<<<< HEAD + /// // example code where clippy issues a warning +>>>>>>> 3ab6aeefb (`to_xx_bytes` implemented, `from_xx_bytes` todo) +======= + /// let _x = 2i32.to_le_bytes(); + /// let _y = 2i64.to_le_bytes(); + /// ``` + #[clippy::version = "1.71.0"] + pub LITTLE_ENDIAN_BYTES, + restriction, + "disallows usage of the `to_le_bytes` method" +} + +declare_clippy_lint! { + /// ### What it does + /// Checks for the usage of the `to_be_bytes` method and/or the function `from_be_bytes`. + /// + /// ### Why is this bad? + /// It's not, but some may wish to lint usage of this method, either to suggest using the host + /// endianness or little endian. + /// + /// ### Example + /// ```rust,ignore + /// let _x = 2i32.to_be_bytes(); + /// let _y = 2i64.to_be_bytes(); +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) + /// ``` + #[clippy::version = "1.71.0"] + pub BIG_ENDIAN_BYTES, + restriction, + "disallows usage of the `to_be_bytes` method" +} + +declare_lint_pass!(EndianBytes => [HOST_ENDIAN_BYTES, LITTLE_ENDIAN_BYTES, BIG_ENDIAN_BYTES]); + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 95e8c0b35 (don't allocate the names) +const HOST_NAMES: [&str; 2] = ["from_ne_bytes", "to_ne_bytes"]; +const LITTLE_NAMES: [&str; 2] = ["from_le_bytes", "to_le_bytes"]; +const BIG_NAMES: [&str; 2] = ["from_be_bytes", "to_be_bytes"]; + +<<<<<<< HEAD +======= +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +======= +>>>>>>> 95e8c0b35 (don't allocate the names) +#[derive(Clone, Debug)] +enum LintKind { + Host, + Little, + Big, +} + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +#[derive(Clone, Copy, PartialEq)] +======= +>>>>>>> a6c36556c (use enum for `prefix` instead of `&str`) +======= +#[derive(Clone, Copy, PartialEq)] +>>>>>>> 7fe200ed0 (derive Copy/PartialEq for `Prefix`) +enum Prefix { + From, + To, +} + +<<<<<<< HEAD +======= +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +======= +>>>>>>> a6c36556c (use enum for `prefix` instead of `&str`) +impl LintKind { + fn allowed(&self, cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + is_lint_allowed(cx, self.as_lint(), expr.hir_id) + } + + fn as_lint(&self) -> &'static Lint { + match self { + LintKind::Host => HOST_ENDIAN_BYTES, + LintKind::Little => LITTLE_ENDIAN_BYTES, + LintKind::Big => BIG_ENDIAN_BYTES, + } + } + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + fn as_name(&self, prefix: Prefix) -> &str { + let index = usize::from(prefix == Prefix::To); + + match self { + LintKind::Host => HOST_NAMES[index], + LintKind::Little => LITTLE_NAMES[index], + LintKind::Big => BIG_NAMES[index], +======= + fn to_name(&self, prefix: &str) -> String { + match self { + LintKind::Host => format!("{prefix}_ne_bytes"), + LintKind::Little => format!("{prefix}_le_bytes"), + LintKind::Big => format!("{prefix}_be_bytes"), +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +======= + fn to_name(&self, prefix: &str) -> &str { + match self { + LintKind::Host => { + if prefix == "from" { + HOST_NAMES[0] + } else { + HOST_NAMES[1] + } + }, + LintKind::Little => { + if prefix == "from" { + LITTLE_NAMES[0] + } else { + LITTLE_NAMES[1] + } + }, + LintKind::Big => { + if prefix == "from" { + BIG_NAMES[0] + } else { + BIG_NAMES[1] + } + }, +>>>>>>> 95e8c0b35 (don't allocate the names) +======= + fn as_name(&self, prefix: &Prefix) -> &str { + let index = usize::from(matches!(prefix, Prefix::To)); +======= + fn as_name(&self, prefix: Prefix) -> &str { + let index = usize::from(prefix == Prefix::To); +>>>>>>> 7fe200ed0 (derive Copy/PartialEq for `Prefix`) + + match self { + LintKind::Host => HOST_NAMES[index], + LintKind::Little => LITTLE_NAMES[index], + LintKind::Big => BIG_NAMES[index], +>>>>>>> a6c36556c (use enum for `prefix` instead of `&str`) + } + } +} + +<<<<<<< HEAD +impl LateLintPass<'_> for EndianBytes { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + if in_external_macro(cx.sess(), expr.span) { + return; + } + + if_chain! { + if let ExprKind::MethodCall(method_name, receiver, args, ..) = expr.kind; + if args.is_empty(); + let ty = cx.typeck_results().expr_ty(receiver); + if ty.is_primitive_ty(); + if maybe_lint_endian_bytes(cx, expr, Prefix::To, method_name.ident.name, ty); + then { +======= +======= +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +impl LateLintPass<'_> for EndianBytes { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + if in_external_macro(cx.sess(), expr.span) { + return; + } + + if_chain! { + if let ExprKind::MethodCall(method_name, receiver, args, ..) = expr.kind; + if args.is_empty(); + let ty = cx.typeck_results().expr_ty(receiver); + if ty.is_primitive_ty(); + if maybe_lint_endian_bytes(cx, expr, Prefix::To, method_name.ident.name, ty); + then { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if method_name.ident.name == sym!(to_ne_bytes) { + span_lint_and_help( + cx, + HOST_ENDIAN_BYTES, + expr.span, + "use of the method `to_ne_bytes`", + None, + "consider specifying the desired endianness", + ); + } else if method_name.ident.name == sym!(to_le_bytes) { + span_lint_and_then(cx, LITTLE_ENDIAN_BYTES, expr.span, "use of the method `to_le_bytes`", |diag| { + if is_lint_allowed(cx, BIG_ENDIAN_BYTES, expr.hir_id) { + diag.help("use `to_be_bytes` instead"); + } + }); + } else if method_name.ident.name == sym!(to_be_bytes) { + span_lint_and_then(cx, BIG_ENDIAN_BYTES, expr.span, "use of the method `to_be_bytes`", |diag| { + if is_lint_allowed(cx, LITTLE_ENDIAN_BYTES, expr.hir_id) { + diag.help("use `to_le_bytes` instead"); + } + }); + } + + // don't waste time also checking from_**_bytes +>>>>>>> 3ab6aeefb (`to_xx_bytes` implemented, `from_xx_bytes` todo) +======= +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) + return; +======= + if try_lint_endian_bytes(cx, expr, "to", method_name.ident.name, ty) { + return; + } +>>>>>>> 04b7cae37 (refine output) +======= + return; +>>>>>>> 80ae1ec12 (unidiomatic `if_chain!`) + } + } + +<<<<<<< HEAD +<<<<<<< HEAD + if_chain! { + if let ExprKind::Call(function, ..) = expr.kind; + if let ExprKind::Path(qpath) = function.kind; + if let Some(def_id) = cx.qpath_res(&qpath, function.hir_id).opt_def_id(); + if let Some(function_name) = cx.get_def_path(def_id).last(); + let ty = cx.typeck_results().expr_ty(expr); + if ty.is_primitive_ty(); + then { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + maybe_lint_endian_bytes(cx, expr, Prefix::From, *function_name, ty); +======= + span_lint_and_help( + cx, + HOST_ENDIAN_BYTES, + expr.span, + "use of the method `from_ne_bytes`", + None, + &format!("consider specifying the desired endianness: {expr:?}"), + ); + +======= +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) + if_chain! { + if let ExprKind::Call(function, ..) = expr.kind; + if let ExprKind::Path(qpath) = function.kind; + if let Some(def_id) = cx.qpath_res(&qpath, function.hir_id).opt_def_id(); + if let Some(function_name) = cx.get_def_path(def_id).last(); + let ty = cx.typeck_results().expr_ty(expr); + if ty.is_primitive_ty(); + then { +<<<<<<< HEAD +<<<<<<< HEAD + if match_def_path(cx, function_def_id, &["from_ne_bytes"]) { + span_lint_and_help( + cx, + HOST_ENDIAN_BYTES, + expr.span, + "use of the method `from_ne_bytes`", + None, + "consider specifying the desired endianness", + ); + } else if match_def_path(cx, function_def_id, &["from_le_bytes"]) { + span_lint_and_then(cx, LITTLE_ENDIAN_BYTES, expr.span, "use of the method `from_le_bytes`", |diag| { + if is_lint_allowed(cx, BIG_ENDIAN_BYTES, expr.hir_id) { + diag.help("use `from_be_bytes` instead"); + } + }); + } else if match_def_path(cx, function_def_id, &["from_be_bytes"]) { + span_lint_and_then(cx, BIG_ENDIAN_BYTES, expr.span, "use of the method `from_be_bytes`", |diag| { + if is_lint_allowed(cx, LITTLE_ENDIAN_BYTES, expr.hir_id) { + diag.help("use `from_le_bytes` instead"); + } + }); + } +>>>>>>> 3ab6aeefb (`to_xx_bytes` implemented, `from_xx_bytes` todo) +======= + try_lint_endian_bytes(cx, expr, "from", *function_name); +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +======= + try_lint_endian_bytes(cx, expr, "from", *function_name, ty); +>>>>>>> 04b7cae37 (refine output) +======= + maybe_lint_endian_bytes(cx, expr, "from", *function_name, ty); +>>>>>>> 95e8c0b35 (don't allocate the names) +======= + maybe_lint_endian_bytes(cx, expr, &Prefix::From, *function_name, ty); +>>>>>>> a6c36556c (use enum for `prefix` instead of `&str`) +======= + maybe_lint_endian_bytes(cx, expr, Prefix::From, *function_name, ty); +>>>>>>> 7fe200ed0 (derive Copy/PartialEq for `Prefix`) + } + } + } +} +<<<<<<< HEAD +<<<<<<< HEAD + +<<<<<<< HEAD +<<<<<<< HEAD +fn maybe_lint_endian_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, prefix: Prefix, name: Symbol, ty: Ty<'_>) -> bool { + let ne = LintKind::Host.as_name(prefix); + let le = LintKind::Little.as_name(prefix); + let be = LintKind::Big.as_name(prefix); +======= + +<<<<<<< HEAD +fn try_lint_endian_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, prefix: &str, name: Symbol, ty: Ty<'_>) -> bool { + let ne = format!("{prefix}_ne_bytes"); + let le = format!("{prefix}_le_bytes"); + let be = format!("{prefix}_be_bytes"); +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +======= +fn maybe_lint_endian_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, prefix: &str, name: Symbol, ty: Ty<'_>) -> bool { + let ne = LintKind::Host.to_name(prefix); + let le = LintKind::Little.to_name(prefix); + let be = LintKind::Big.to_name(prefix); +>>>>>>> 95e8c0b35 (don't allocate the names) +======= +fn maybe_lint_endian_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, prefix: &Prefix, name: Symbol, ty: Ty<'_>) -> bool { +======= +fn maybe_lint_endian_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, prefix: Prefix, name: Symbol, ty: Ty<'_>) -> bool { +>>>>>>> 7fe200ed0 (derive Copy/PartialEq for `Prefix`) + let ne = LintKind::Host.as_name(prefix); + let le = LintKind::Little.as_name(prefix); + let be = LintKind::Big.as_name(prefix); +>>>>>>> a6c36556c (use enum for `prefix` instead of `&str`) + + let (lint, other_lints) = match name.as_str() { + name if name == ne => ((&LintKind::Host), [(&LintKind::Little), (&LintKind::Big)]), + name if name == le => ((&LintKind::Little), [(&LintKind::Host), (&LintKind::Big)]), + name if name == be => ((&LintKind::Big), [(&LintKind::Host), (&LintKind::Little)]), + _ => return false, + }; + + let mut help = None; + + 'build_help: { + // all lints disallowed, don't give help here + if [&[lint], other_lints.as_slice()] + .concat() + .iter() + .all(|lint| !lint.allowed(cx, expr)) + { + break 'build_help; + } + + // ne_bytes and all other lints allowed +<<<<<<< HEAD +<<<<<<< HEAD + if lint.as_name(prefix) == ne && other_lints.iter().all(|lint| lint.allowed(cx, expr)) { +======= + if lint.to_name(prefix) == ne && other_lints.iter().all(|lint| lint.allowed(cx, expr)) { +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +======= + if lint.as_name(prefix) == ne && other_lints.iter().all(|lint| lint.allowed(cx, expr)) { +>>>>>>> a6c36556c (use enum for `prefix` instead of `&str`) + help = Some(Cow::Borrowed("specify the desired endianness explicitly")); + break 'build_help; + } + + // le_bytes where ne_bytes allowed but be_bytes is not, or le_bytes where ne_bytes allowed but + // le_bytes is not +<<<<<<< HEAD +<<<<<<< HEAD + if (lint.as_name(prefix) == le || lint.as_name(prefix) == be) && LintKind::Host.allowed(cx, expr) { +======= + if (lint.to_name(prefix) == le || lint.to_name(prefix) == be) && LintKind::Host.allowed(cx, expr) { +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +======= + if (lint.as_name(prefix) == le || lint.as_name(prefix) == be) && LintKind::Host.allowed(cx, expr) { +>>>>>>> a6c36556c (use enum for `prefix` instead of `&str`) + help = Some(Cow::Borrowed("use the native endianness instead")); + break 'build_help; + } + + let allowed_lints = other_lints.iter().filter(|lint| lint.allowed(cx, expr)); + let len = allowed_lints.clone().count(); + + let mut help_str = "use ".to_owned(); + + for (i, lint) in allowed_lints.enumerate() { + let only_one = len == 1; + if !only_one { + help_str.push_str("either of "); + } + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + help_str.push_str(&format!("`{ty}::{}` ", lint.as_name(prefix))); +======= + help_str.push_str(&format!("`{}` ", lint.to_name(prefix))); +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +======= + help_str.push_str(&format!("`{ty}::{}` ", lint.to_name(prefix))); +>>>>>>> 04b7cae37 (refine output) +======= + help_str.push_str(&format!("`{ty}::{}` ", lint.as_name(prefix))); +>>>>>>> a6c36556c (use enum for `prefix` instead of `&str`) + + if i != len && !only_one { + help_str.push_str("or "); + } + } + + help = Some(Cow::Owned(help_str + "instead")); + } + + span_lint_and_then( + cx, + lint.as_lint(), + expr.span, +<<<<<<< HEAD +<<<<<<< HEAD + &format!( + "usage of the {}`{ty}::{}`{}", + if prefix == Prefix::From { "function " } else { "" }, + lint.as_name(prefix), + if prefix == Prefix::To { " method" } else { "" }, + ), +======= + &format!("usage of the method `{}`", lint.to_name(prefix)), +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +======= + &format!( + "usage of the {}`{ty}::{}`{}", + if prefix == Prefix::From { "function " } else { "" }, + lint.as_name(prefix), + if prefix == Prefix::To { " method" } else { "" }, + ), +>>>>>>> 04b7cae37 (refine output) + move |diag| { + if let Some(help) = help { + diag.help(help); + } + }, + ); + + true +} +<<<<<<< HEAD +======= +>>>>>>> 3ab6aeefb (`to_xx_bytes` implemented, `from_xx_bytes` todo) +======= +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index ee5a875ade7b..49aae6b37454 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -1,18 +1,14 @@ -use clippy_utils::higher; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::{reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context}; use clippy_utils::{ - can_move_expr_to_closure_no_visit, - diagnostics::span_lint_and_sugg, - is_expr_final_block_expr, is_expr_used_or_unified, match_def_path, paths, peel_hir_expr_while, - source::{reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context}, - SpanlessEq, + can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified, match_def_path, + paths, peel_hir_expr_while, SpanlessEq, }; use core::fmt::{self, Write}; use rustc_errors::Applicability; -use rustc_hir::{ - hir_id::HirIdSet, - intravisit::{walk_expr, Visitor}, - Block, Expr, ExprKind, Guard, HirId, Let, Pat, Stmt, StmtKind, UnOp, -}; +use rustc_hir::hir_id::HirIdSet; +use rustc_hir::intravisit::{walk_expr, Visitor}; +use rustc_hir::{Block, Expr, ExprKind, Guard, HirId, Let, Pat, Stmt, StmtKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{Span, SyntaxContext, DUMMY_SP}; @@ -186,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for HashMapPass { MAP_ENTRY, expr.span, &format!("usage of `contains_key` followed by `insert` on a `{}`", map_ty.name()), - "try this", + "try", sugg, app, ); diff --git a/clippy_lints/src/enum_clike.rs b/clippy_lints/src/enum_clike.rs index e275efaba25f..d85650712db8 100644 --- a/clippy_lints/src/enum_clike.rs +++ b/clippy_lints/src/enum_clike.rs @@ -51,7 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant { .const_eval_poly(def_id.to_def_id()) .ok() .map(|val| rustc_middle::mir::ConstantKind::from_value(val, ty)); - if let Some(Constant::Int(val)) = constant.and_then(|c| miri_to_const(cx.tcx, c)) { + if let Some(Constant::Int(val)) = constant.and_then(|c| miri_to_const(cx, c)) { if let ty::Adt(adt, _) = ty.kind() { if adt.is_enum() { ty = adt.repr().discr_type().to_ty(cx.tcx); diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs index 4c69dacf381a..d4df6f7aa2d0 100644 --- a/clippy_lints/src/enum_variants.rs +++ b/clippy_lints/src/enum_variants.rs @@ -1,9 +1,9 @@ //! lint on enum variants that are prefixed or suffixed by the same characters -use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; +use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_hir}; use clippy_utils::source::is_present_in_source; use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start}; -use rustc_hir::{EnumDef, Item, ItemKind, Variant}; +use rustc_hir::{EnumDef, Item, ItemKind, OwnerId, Variant}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; @@ -105,18 +105,20 @@ declare_clippy_lint! { } pub struct EnumVariantNames { - modules: Vec<(Symbol, String)>, + modules: Vec<(Symbol, String, OwnerId)>, threshold: u64, avoid_breaking_exported_api: bool, + allow_private_module_inception: bool, } impl EnumVariantNames { #[must_use] - pub fn new(threshold: u64, avoid_breaking_exported_api: bool) -> Self { + pub fn new(threshold: u64, avoid_breaking_exported_api: bool, allow_private_module_inception: bool) -> Self { Self { modules: Vec::new(), threshold, avoid_breaking_exported_api, + allow_private_module_inception, } } } @@ -135,9 +137,10 @@ fn check_enum_start(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_> && name.chars().nth(item_name_chars).map_or(false, |c| !c.is_lowercase()) && name.chars().nth(item_name_chars + 1).map_or(false, |c| !c.is_numeric()) { - span_lint( + span_lint_hir( cx, ENUM_VARIANT_NAMES, + variant.hir_id, variant.span, "variant name starts with the enum's name", ); @@ -149,9 +152,10 @@ fn check_enum_end(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>) let item_name_chars = item_name.chars().count(); if count_match_end(item_name, name).char_count == item_name_chars { - span_lint( + span_lint_hir( cx, ENUM_VARIANT_NAMES, + variant.hir_id, variant.span, "variant name ends with the enum's name", ); @@ -250,18 +254,19 @@ impl LateLintPass<'_> for EnumVariantNames { let item_name = item.ident.name.as_str(); let item_camel = to_camel_case(item_name); if !item.span.from_expansion() && is_present_in_source(cx, item.span) { - if let Some((mod_name, mod_camel)) = self.modules.last() { + if let [.., (mod_name, mod_camel, owner_id)] = &*self.modules { // constants don't have surrounding modules if !mod_camel.is_empty() { - if mod_name == &item.ident.name { - if let ItemKind::Mod(..) = item.kind { - span_lint( - cx, - MODULE_INCEPTION, - item.span, - "module has the same name as its containing module", - ); - } + if mod_name == &item.ident.name + && let ItemKind::Mod(..) = item.kind + && (!self.allow_private_module_inception || cx.tcx.visibility(owner_id.def_id).is_public()) + { + span_lint( + cx, + MODULE_INCEPTION, + item.span, + "module has the same name as its containing module", + ); } // The `module_name_repetitions` lint should only trigger if the item has the module in its // name. Having the same name is accepted. @@ -300,6 +305,6 @@ impl LateLintPass<'_> for EnumVariantNames { check_variant(cx, self.threshold, def, item_name, item.span); } } - self.modules.push((item.ident.name, item_camel)); + self.modules.push((item.ident.name, item_camel, item.owner_id)); } } diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index d6ab4c25e83e..09343fe9314b 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -1,6 +1,5 @@ use clippy_utils::diagnostics::span_lint_hir; -use rustc_hir::intravisit; -use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind}; +use rustc_hir::{self, intravisit, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; @@ -92,11 +91,21 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { if trait_item.id.owner_id.def_id == fn_def_id { // be sure we have `self` parameter in this function if trait_item.kind == (AssocItemKind::Fn { has_self: true }) { +<<<<<<< HEAD +======= +<<<<<<< HEAD + trait_self_ty = + Some(TraitRef::identity(cx.tcx, trait_item.id.owner_id.to_def_id()).self_ty()); +======= +>>>>>>> 4da6e7e06 (rebase attempt) trait_self_ty = Some( TraitRef::identity(cx.tcx, trait_item.id.owner_id.to_def_id()) - .self_ty() - .skip_binder(), + .self_ty(), ); +<<<<<<< HEAD +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) } } } diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index b2071f4dcb1e..58e62d1f3d37 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -120,6 +120,13 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Arc); if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Rc); if let ty::Closure(_, substs) = *closure_ty.kind(); + // Don't lint if this is an inclusive range expression. + // They desugar to a call to `RangeInclusiveNew` which would have odd suggestions. (#10684) + if !matches!(higher::Range::hir(body.value), Some(higher::Range { + start: Some(_), + end: Some(_), + limits: rustc_ast::RangeLimits::Closed + })); then { span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| { if let Some(mut snippet) = snippet_opt(cx, callee.span) { @@ -136,6 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { // Mutable closure is used after current expr; we cannot consume it. snippet = format!("&mut {snippet}"); } + diag.span_suggestion( expr.span, "replace the closure with the function itself", @@ -243,7 +251,7 @@ fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, substs | ty::Ref(..) | ty::Slice(_) | ty::Tuple(_) => { - format!("<{}>", EarlyBinder(ty).subst(cx.tcx, substs)) + format!("<{}>", EarlyBinder::bind(ty).subst(cx.tcx, substs)) }, _ => ty.to_string(), } diff --git a/clippy_lints/src/excessive_nesting.rs b/clippy_lints/src/excessive_nesting.rs new file mode 100644 index 000000000000..a447fa7d132d --- /dev/null +++ b/clippy_lints/src/excessive_nesting.rs @@ -0,0 +1,625 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5da34559e (Check if from proc macro and better tests) +use clippy_utils::{diagnostics::span_lint_and_help, source::snippet}; +use rustc_ast::{ + node_id::NodeSet, + visit::{walk_block, walk_item, Visitor}, + Block, Crate, Inline, Item, ItemKind, ModKind, NodeId, +======= +use clippy_utils::diagnostics::span_lint_and_help; +use rustc_ast::{ +<<<<<<< HEAD +<<<<<<< HEAD + node_id::NodeId, + ptr::P, + visit::{FnKind, Visitor}, + Arm, AssocItemKind, Block, Expr, ExprKind, Inline, Item, ItemKind, Local, LocalKind, ModKind, ModSpans, Pat, + PatKind, Stmt, StmtKind, +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + visit::{walk_block, walk_item, Visitor}, + Block, Crate, Inline, Item, ItemKind, ModKind, +>>>>>>> 88143ac29 (decided against reinventing the wheel) +======= + node_id::NodeSet, + visit::{walk_block, walk_item, Visitor}, + Block, Crate, Inline, Item, ItemKind, ModKind, NodeId, +>>>>>>> 378d77584 (work with lint attributes) +}; +======= +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::source::snippet; +use rustc_ast::node_id::NodeSet; +use rustc_ast::visit::{walk_block, walk_item, Visitor}; +use rustc_ast::{Block, Crate, Inline, Item, ItemKind, ModKind, NodeId}; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::Span; +<<<<<<< HEAD +<<<<<<< HEAD + +declare_clippy_lint! { + /// ### What it does + /// Checks for blocks which are nested beyond a certain threshold. + /// + /// Note: Even though this lint is warn-by-default, it will only trigger if a maximum nesting level is defined in the clippy.toml file. + /// + /// ### Why is this bad? + /// It can severely hinder readability. +======= +use thin_vec::ThinVec; +======= +>>>>>>> 88143ac29 (decided against reinventing the wheel) + +declare_clippy_lint! { + /// ### What it does + /// Checks for blocks which are nested beyond a certain threshold. + /// + /// Note: Even though this lint is warn-by-default, it will only trigger if a maximum nesting level is defined in the clippy.toml file. + /// + /// ### Why is this bad? + /// It can severely hinder readability. + /// +<<<<<<< HEAD + /// ### Known issues + /// + /// Nested inline modules will all be linted, rather than just the outermost one + /// that applies. This makes the output a bit verbose. +>>>>>>> e68dbc330 (add `excessive_nesting`) + /// +======= +>>>>>>> 88143ac29 (decided against reinventing the wheel) + /// ### Example + /// An example clippy.toml configuration: + /// ```toml + /// # clippy.toml + /// excessive-nesting-threshold = 3 + /// ``` +<<<<<<< HEAD +<<<<<<< HEAD + /// ```rust,ignore + /// // lib.rs +======= + /// lib.rs: + /// ```rust,ignore +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + /// ```rust,ignore + /// // lib.rs +>>>>>>> b7fedb88c (Update excessive_nesting.rs) + /// pub mod a { + /// pub struct X; + /// impl X { + /// pub fn run(&self) { + /// if true { + /// // etc... + /// } + /// } + /// } + /// } +<<<<<<< HEAD +<<<<<<< HEAD + /// ``` + /// Use instead: + /// ```rust,ignore + /// // a.rs +======= +======= + /// ``` +>>>>>>> b7fedb88c (Update excessive_nesting.rs) + /// Use instead: + /// ```rust,ignore +<<<<<<< HEAD +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + /// // a.rs +>>>>>>> b7fedb88c (Update excessive_nesting.rs) + /// fn private_run(x: &X) { + /// if true { + /// // etc... + /// } + /// } + /// + /// pub struct X; + /// impl X { + /// pub fn run(&self) { + /// private_run(self); + /// } + /// } + /// ``` +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + /// ```rust,ignore + /// // lib.rs +======= + /// ```rust,ignore +<<<<<<< HEAD + /// lib// .rs +>>>>>>> b7fedb88c (Update excessive_nesting.rs) +======= + /// // lib.rs +>>>>>>> d1957b87c (Update excessive_nesting.rs) + /// pub mod a; + /// ``` + #[clippy::version = "1.70.0"] + pub EXCESSIVE_NESTING, + complexity, +<<<<<<< HEAD +======= +======= + /// lib.rs: + /// ```rust,ignore + /// pub mod a; + /// ``` +>>>>>>> 378d77584 (work with lint attributes) + #[clippy::version = "1.70.0"] + pub EXCESSIVE_NESTING, + restriction, +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= +>>>>>>> 725399a17 (move to `complexity` but don't lint by default) + "checks for blocks nested beyond a certain threshold" +} +impl_lint_pass!(ExcessiveNesting => [EXCESSIVE_NESTING]); + +<<<<<<< HEAD +<<<<<<< HEAD +#[derive(Clone)] +pub struct ExcessiveNesting { + pub excessive_nesting_threshold: u64, + pub nodes: NodeSet, +} + +impl ExcessiveNesting { + pub fn check_node_id(&self, cx: &EarlyContext<'_>, span: Span, node_id: NodeId) { + if self.nodes.contains(&node_id) { + span_lint_and_help( + cx, + EXCESSIVE_NESTING, + span, + "this block is too nested", + None, + "try refactoring your code to minimize nesting", + ); + } + } +} + +impl EarlyLintPass for ExcessiveNesting { + fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) { + if self.excessive_nesting_threshold == 0 { + return; + } + +<<<<<<< HEAD + let mut visitor = NestingVisitor { + conf: self, + cx, + nest_level: 0, + }; + + for item in &krate.items { + visitor.visit_item(item); + } + } + + fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) { + self.check_node_id(cx, block.span, block.id); + } + + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + self.check_node_id(cx, item.span, item.id); +======= +#[derive(Clone, Copy)] +======= +#[derive(Clone)] +>>>>>>> 378d77584 (work with lint attributes) +pub struct ExcessiveNesting { + pub excessive_nesting_threshold: u64, + pub nodes: NodeSet, +} + +impl ExcessiveNesting { + pub fn check_node_id(&self, cx: &EarlyContext<'_>, span: Span, node_id: NodeId) { + if self.nodes.contains(&node_id) { + span_lint_and_help( + cx, + EXCESSIVE_NESTING, + span, + "this block is too nested", + None, + "try refactoring your code to minimize nesting", + ); + } + } +} + +impl EarlyLintPass for ExcessiveNesting { + fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) { +======= +>>>>>>> 5da34559e (Check if from proc macro and better tests) + let mut visitor = NestingVisitor { + conf: self, + cx, + nest_level: 0, + }; + + for item in &krate.items { + visitor.visit_item(item); + } +<<<<<<< HEAD + .visit_item(item); +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= +>>>>>>> 88143ac29 (decided against reinventing the wheel) + } + + fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) { + self.check_node_id(cx, block.span, block.id); + } + + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + self.check_node_id(cx, item.span, item.id); + } +} + +struct NestingVisitor<'conf, 'cx> { +<<<<<<< HEAD +<<<<<<< HEAD + conf: &'conf mut ExcessiveNesting, +======= + conf: &'conf ExcessiveNesting, +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + conf: &'conf mut ExcessiveNesting, +>>>>>>> 378d77584 (work with lint attributes) + cx: &'cx EarlyContext<'cx>, + nest_level: u64, +} + +<<<<<<< HEAD +<<<<<<< HEAD +impl NestingVisitor<'_, '_> { + fn check_indent(&mut self, span: Span, id: NodeId) -> bool { + if self.nest_level > self.conf.excessive_nesting_threshold && !in_external_macro(self.cx.sess(), span) { + self.conf.nodes.insert(id); + + return true; + } + + false + } +} + +impl<'conf, 'cx> Visitor<'_> for NestingVisitor<'conf, 'cx> { + fn visit_block(&mut self, block: &Block) { + if block.span.from_expansion() { + return; + } + + // TODO: This should be rewritten using `LateLintPass` so we can use `is_from_proc_macro` instead, + // but for now, this is fine. + let snippet = snippet(self.cx, block.span, "{}").trim().to_owned(); + if !snippet.starts_with('{') || !snippet.ends_with('}') { + return; + } + + self.nest_level += 1; + + if !self.check_indent(block.span, block.id) { + walk_block(self, block); +======= +impl<'conf, 'cx> Visitor<'_> for NestingVisitor<'conf, 'cx> { + fn visit_local(&mut self, local: &Local) { + self.visit_pat(&local.pat); +======= +impl NestingVisitor<'_, '_> { + fn check_indent(&mut self, span: Span, id: NodeId) -> bool { + if self.nest_level > self.conf.excessive_nesting_threshold && !in_external_macro(self.cx.sess(), span) { +<<<<<<< HEAD + span_lint_and_help( + self.cx, + EXCESSIVE_NESTING, + span, + "this block is too nested", + None, + "try refactoring your code to minimize nesting", + ); +>>>>>>> 88143ac29 (decided against reinventing the wheel) +======= + self.conf.nodes.insert(id); +>>>>>>> 378d77584 (work with lint attributes) + + return true; + } + + false + } +} + +impl<'conf, 'cx> Visitor<'_> for NestingVisitor<'conf, 'cx> { + fn visit_block(&mut self, block: &Block) { + if block.span.from_expansion() { + return; + } + + self.nest_level += 1; + +<<<<<<< HEAD +<<<<<<< HEAD + if !check_indent(self, block.span) { + for stmt in &block.stmts { + self.visit_stmt(stmt); + } +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + if !self.check_indent(block.span) { +======= + if !self.check_indent(block.span, block.id) { +>>>>>>> 378d77584 (work with lint attributes) + walk_block(self, block); +>>>>>>> 88143ac29 (decided against reinventing the wheel) + } + + self.nest_level -= 1; + } + +<<<<<<< HEAD +<<<<<<< HEAD + fn visit_item(&mut self, item: &Item) { + if item.span.from_expansion() { + return; + } + + match &item.kind { + ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _)) => { + self.nest_level += 1; + + if !self.check_indent(item.span, item.id) { + walk_item(self, item); + } + + self.nest_level -= 1; + }, + // Reset nesting level for non-inline modules (since these are in another file) + ItemKind::Mod(..) => walk_item( + &mut NestingVisitor { + conf: self.conf, + cx: self.cx, + nest_level: 0, + }, + item, + ), + _ => walk_item(self, item), + } + } +} +======= + fn visit_stmt(&mut self, stmt: &Stmt) { + match &stmt.kind { + StmtKind::Local(local) => self.visit_local(local), + StmtKind::Item(item) => self.visit_item(item), + StmtKind::Expr(expr) | StmtKind::Semi(expr) => self.visit_expr(expr), + _ => (), + } + } + + fn visit_arm(&mut self, arm: &Arm) { + self.visit_pat(&arm.pat); + if let Some(expr) = &arm.guard { + self.visit_expr(expr); + } + self.visit_expr(&arm.body); + } + + // TODO: Is this necessary? + fn visit_pat(&mut self, pat: &Pat) { + match &pat.kind { + PatKind::Box(pat) | PatKind::Ref(pat, ..) | PatKind::Paren(pat) => self.visit_pat(pat), + PatKind::Lit(expr) => self.visit_expr(expr), + PatKind::Range(start, end, ..) => { + if let Some(expr) = start { + self.visit_expr(expr); + } + if let Some(expr) = end { + self.visit_expr(expr); + } + }, + PatKind::Ident(.., pat) if let Some(pat) = pat => { + self.visit_pat(pat); + }, + PatKind::Struct(.., pat_fields, _) => { + for pat_field in pat_fields { + self.visit_pat(&pat_field.pat); + } + }, + PatKind::TupleStruct(.., pats) | PatKind::Or(pats) | PatKind::Tuple(pats) | PatKind::Slice(pats) => { + for pat in pats { + self.visit_pat(pat); + } + }, + _ => (), + } + } + + fn visit_expr(&mut self, expr: &Expr) { + // This is a mess, but really all it does is extract every expression from every applicable variant + // of ExprKind until it finds a Block. + // TODO: clippy_utils has the two functions for_each_expr and for_each_expr_with_closures, can those + // be used here or are they not applicable for this case? + match &expr.kind { + ExprKind::ConstBlock(anon_const) => self.visit_expr(&anon_const.value), + ExprKind::Call(.., args) => { + for expr in args { + self.visit_expr(expr); + } + }, + ExprKind::MethodCall(method_call) => { + for expr in &method_call.args { + self.visit_expr(expr); + } + }, + ExprKind::Tup(exprs) | ExprKind::Array(exprs) => { + for expr in exprs { + self.visit_expr(expr); + } + }, + ExprKind::Binary(.., left, right) + | ExprKind::Assign(left, right, ..) + | ExprKind::AssignOp(.., left, right) + | ExprKind::Index(left, right) => { + self.visit_expr(left); + self.visit_expr(right); + }, + ExprKind::Let(pat, expr, ..) => { + self.visit_pat(pat); + self.visit_expr(expr); + }, + ExprKind::Unary(.., expr) + | ExprKind::Await(expr) + | ExprKind::Field(expr, ..) + | ExprKind::AddrOf(.., expr) + | ExprKind::Try(expr) => { + self.visit_expr(expr); + }, + ExprKind::Repeat(expr, anon_const) => { + self.visit_expr(expr); + self.visit_expr(&anon_const.value); + }, + ExprKind::If(expr, block, else_expr) => { + self.visit_expr(expr); + self.visit_block(block); + + if let Some(expr) = else_expr { + self.visit_expr(expr); + } + }, + ExprKind::While(expr, block, ..) => { + self.visit_expr(expr); + self.visit_block(block); + }, + ExprKind::ForLoop(pat, expr, block, ..) => { + self.visit_pat(pat); + self.visit_expr(expr); + self.visit_block(block); + }, + ExprKind::Loop(block, ..) + | ExprKind::Block(block, ..) + | ExprKind::Async(.., block) + | ExprKind::TryBlock(block) => { + self.visit_block(block); + }, + ExprKind::Match(expr, arms) => { + self.visit_expr(expr); + + for arm in arms { + self.visit_arm(arm); + } + }, + ExprKind::Closure(closure) => self.visit_expr(&closure.body), + ExprKind::Range(start, end, ..) => { + if let Some(expr) = start { + self.visit_expr(expr); + } + if let Some(expr) = end { + self.visit_expr(expr); + } + }, + ExprKind::Break(.., expr) | ExprKind::Ret(expr) | ExprKind::Yield(expr) | ExprKind::Yeet(expr) => { + if let Some(expr) = expr { + self.visit_expr(expr); + } + }, + ExprKind::Struct(struct_expr) => { + for field in &struct_expr.fields { + self.visit_expr(&field.expr); + } + }, + _ => (), + } + } + + fn visit_fn(&mut self, fk: FnKind<'_>, _: Span, _: NodeId) { + match fk { + FnKind::Fn(.., block) if let Some(block) = block => self.visit_block(block), + FnKind::Closure(.., expr) => self.visit_expr(expr), + // :/ + FnKind::Fn(..) => (), + } + } + +======= +>>>>>>> 88143ac29 (decided against reinventing the wheel) + fn visit_item(&mut self, item: &Item) { + if item.span.from_expansion() { + return; + } + + match &item.kind { + ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _)) => { + self.nest_level += 1; + + if !self.check_indent(item.span, item.id) { + walk_item(self, item); + } + + self.nest_level -= 1; + }, + // Reset nesting level for non-inline modules (since these are in another file) + ItemKind::Mod(..) => walk_item( + &mut NestingVisitor { + conf: self.conf, + cx: self.cx, + nest_level: 0, + }, + item, + ), + _ => walk_item(self, item), + } + } +} +<<<<<<< HEAD + +fn check_trait_and_impl(visitor: &mut NestingVisitor<'_, '_>, item: &Item, items: &ThinVec>>) { + visitor.nest_level += 1; + + if !check_indent(visitor, item.span) { + for item in items { + match &item.kind { + AssocItemKind::Const(const_item) if let Some(expr) = const_item.expr.as_ref() => { + visitor.visit_expr(expr); + }, + AssocItemKind::Fn(fk) if let Some(block) = fk.body.as_ref() => visitor.visit_block(block), + _ => (), + } + } + } + + visitor.nest_level -= 1; +} + +fn check_indent(visitor: &NestingVisitor<'_, '_>, span: Span) -> bool { + if visitor.nest_level > visitor.conf.excessive_nesting_threshold && !in_external_macro(visitor.cx.sess(), span) { + span_lint_and_help( + visitor.cx, + EXCESSIVE_NESTING, + span, + "this block is too nested", + None, + "try refactoring your code, extraction is often both easier to read and less nested", + ); + + return true; + } + + false +} +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= +>>>>>>> 88143ac29 (decided against reinventing the wheel) diff --git a/clippy_lints/src/explicit_write.rs b/clippy_lints/src/explicit_write.rs index 315df6c714ff..4b9ca8c917e5 100644 --- a/clippy_lints/src/explicit_write.rs +++ b/clippy_lints/src/explicit_write.rs @@ -100,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite { EXPLICIT_WRITE, expr.span, &format!("use of `{used}.unwrap()`"), - "try this", + "try", format!("{prefix}{sugg_mac}!({inputs_snippet})"), applicability, ); diff --git a/clippy_lints/src/extra_unused_type_parameters.rs b/clippy_lints/src/extra_unused_type_parameters.rs index eeb4de8b58f4..c18006a71c26 100644 --- a/clippy_lints/src/extra_unused_type_parameters.rs +++ b/clippy_lints/src/extra_unused_type_parameters.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then}; -use clippy_utils::trait_ref_of_method; +use clippy_utils::{is_from_proc_macro, trait_ref_of_method}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_impl_item, walk_item, walk_param_bound, walk_ty, Visitor}; @@ -11,10 +11,8 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::nested_filter; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{ - def_id::{DefId, LocalDefId}, - Span, -}; +use rustc_span::def_id::{DefId, LocalDefId}; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does @@ -265,6 +263,7 @@ impl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { if let ItemKind::Fn(_, generics, body_id) = item.kind && !self.is_empty_exported_or_macro(cx, item.span, item.owner_id.def_id, body_id) + && !is_from_proc_macro(cx, item) { let mut walker = TypeWalker::new(cx, generics); walk_item(&mut walker, item); diff --git a/clippy_lints/src/float_literal.rs b/clippy_lints/src/float_literal.rs index 6fee7fb308ce..bc092520dfc8 100644 --- a/clippy_lints/src/float_literal.rs +++ b/clippy_lints/src/float_literal.rs @@ -82,19 +82,24 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral { LitFloatType::Suffixed(ast::FloatTy::F64) => Some("f64"), LitFloatType::Unsuffixed => None }; - let (is_whole, mut float_str) = match fty { + let (is_whole, is_inf, mut float_str) = match fty { FloatTy::F32 => { let value = sym_str.parse::().unwrap(); - (value.fract() == 0.0, formatter.format(value)) + (value.fract() == 0.0, value.is_infinite(), formatter.format(value)) }, FloatTy::F64 => { let value = sym_str.parse::().unwrap(); - (value.fract() == 0.0, formatter.format(value)) + + (value.fract() == 0.0, value.is_infinite(), formatter.format(value)) }, }; + if is_inf { + return; + } + if is_whole && !sym_str.contains(|c| c == 'e' || c == 'E') { // Normalize the literal by stripping the fractional portion if sym_str.split('.').next().unwrap() != float_str { diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index f95b628e6c31..85ea8eff51e9 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -1,10 +1,19 @@ +<<<<<<< HEAD +use clippy_utils::consts::Constant::{Int, F32, F64}; +use clippy_utils::consts::{constant, constant_simple, Constant}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::{ + eq_expr_value, get_parent_expr, higher, in_constant, is_no_std_crate, numeric_literal, peel_blocks, sugg, +======= use clippy_utils::consts::{ constant, constant_simple, Constant, Constant::{Int, F32, F64}, }; -use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::higher; -use clippy_utils::{eq_expr_value, get_parent_expr, in_constant, numeric_literal, peel_blocks, sugg}; +use clippy_utils::{ + diagnostics::span_lint_and_sugg, eq_expr_value, get_parent_expr, higher, in_constant, is_no_std_crate, + numeric_literal, peel_blocks, sugg, +>>>>>>> e4f5d83fa (Fixed formatting.) +}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, UnOp}; @@ -113,7 +122,7 @@ declare_lint_pass!(FloatingPointArithmetic => [ // Returns the specialized log method for a given base if base is constant // and is one of 2, 10 and e fn get_specialized_log_method(cx: &LateContext<'_>, base: &Expr<'_>) -> Option<&'static str> { - if let Some((value, _)) = constant(cx, cx.typeck_results(), base) { + if let Some(value) = constant(cx, cx.typeck_results(), base) { if F32(2.0) == value || F64(2.0) == value { return Some("log2"); } else if F32(10.0) == value || F64(10.0) == value { @@ -192,8 +201,8 @@ fn check_ln1p(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) { constant(cx, cx.typeck_results(), lhs), constant(cx, cx.typeck_results(), rhs), ) { - (Some((value, _)), _) if F32(1.0) == value || F64(1.0) == value => rhs, - (_, Some((value, _))) if F32(1.0) == value || F64(1.0) == value => lhs, + (Some(value), _) if F32(1.0) == value || F64(1.0) == value => rhs, + (_, Some(value)) if F32(1.0) == value || F64(1.0) == value => lhs, _ => return, }; @@ -214,7 +223,7 @@ fn check_ln1p(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) { // ranges [-16777215, 16777216) for type f32 as whole number floats outside // this range are lossy and ambiguous. #[expect(clippy::cast_possible_truncation)] -fn get_integer_from_float_constant(value: &Constant) -> Option { +fn get_integer_from_float_constant(value: &Constant<'_>) -> Option { match value { F32(num) if num.fract() == 0.0 => { if (-16_777_215.0..16_777_216.0).contains(num) { @@ -236,7 +245,7 @@ fn get_integer_from_float_constant(value: &Constant) -> Option { fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) { // Check receiver - if let Some((value, _)) = constant(cx, cx.typeck_results(), receiver) { + if let Some(value) = constant(cx, cx.typeck_results(), receiver) { if let Some(method) = if F32(f32_consts::E) == value || F64(f64_consts::E) == value { Some("exp") } else if F32(2.0) == value || F64(2.0) == value { @@ -257,7 +266,7 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: } // Check argument - if let Some((value, _)) = constant(cx, cx.typeck_results(), &args[0]) { + if let Some(value) = constant(cx, cx.typeck_results(), &args[0]) { let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value { ( SUBOPTIMAL_FLOPS, @@ -297,7 +306,7 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: } fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) { - if let Some((value, _)) = constant(cx, cx.typeck_results(), &args[0]) { + if let Some(value) = constant(cx, cx.typeck_results(), &args[0]) { if value == Int(2) { if let Some(parent) = get_parent_expr(cx, expr) { if let Some(grandparent) = get_parent_expr(cx, parent) { @@ -383,8 +392,8 @@ fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option { _ ) = &add_rhs.kind; if lmethod_name.as_str() == "powi" && rmethod_name.as_str() == "powi"; - if let Some((lvalue, _)) = constant(cx, cx.typeck_results(), largs_1); - if let Some((rvalue, _)) = constant(cx, cx.typeck_results(), rargs_1); + if let Some(lvalue) = constant(cx, cx.typeck_results(), largs_1); + if let Some(rvalue) = constant(cx, cx.typeck_results(), rargs_1); if Int(2) == lvalue && Int(2) == rvalue; then { return Some(format!("{}.hypot({})", Sugg::hir(cx, largs_0, "..").maybe_par(), Sugg::hir(cx, rargs_0, ".."))); @@ -415,7 +424,7 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::Binary(Spanned { node: BinOpKind::Sub, .. }, lhs, rhs) = expr.kind; if cx.typeck_results().expr_ty(lhs).is_floating_point(); - if let Some((value, _)) = constant(cx, cx.typeck_results(), rhs); + if let Some(value) = constant(cx, cx.typeck_results(), rhs); if F32(1.0) == value || F64(1.0) == value; if let ExprKind::MethodCall(path, self_arg, ..) = &lhs.kind; if cx.typeck_results().expr_ty(self_arg).is_floating_point(); @@ -668,8 +677,8 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { mul_lhs, mul_rhs, ) = &div_lhs.kind; - if let Some((rvalue, _)) = constant(cx, cx.typeck_results(), div_rhs); - if let Some((lvalue, _)) = constant(cx, cx.typeck_results(), mul_rhs); + if let Some(rvalue) = constant(cx, cx.typeck_results(), div_rhs); + if let Some(lvalue) = constant(cx, cx.typeck_results(), mul_rhs); then { // TODO: also check for constant values near PI/180 or 180/PI if (F32(f32_consts::PI) == rvalue || F64(f64_consts::PI) == rvalue) && @@ -730,15 +739,23 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - // All of these operations are currently not const. + // All of these operations are currently not const and are in std. +<<<<<<< HEAD +<<<<<<< HEAD if in_constant(cx, expr.hir_id) { +======= + if in_constant(cx, expr.hir_id) || is_no_std_crate(cx) { +>>>>>>> 574905424 (globally ignore `#[no_std]` crates) +======= + if in_constant(cx, expr.hir_id) { +>>>>>>> 0dd2501e0 (Don't ignore `check_radians`) return; } if let ExprKind::MethodCall(path, receiver, args, _) = &expr.kind { let recv_ty = cx.typeck_results().expr_ty(receiver); - if recv_ty.is_floating_point() { + if recv_ty.is_floating_point() && !is_no_std_crate(cx) { match path.ident.name.as_str() { "ln" => check_ln1p(cx, expr, receiver), "log" => check_log_base(cx, expr, receiver, args), @@ -749,10 +766,12 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { } } } else { - check_expm1(cx, expr); - check_mul_add(cx, expr); - check_custom_abs(cx, expr); - check_log_division(cx, expr); + if !is_no_std_crate(cx) { + check_expm1(cx, expr); + check_mul_add(cx, expr); + check_custom_abs(cx, expr); + check_log_division(cx, expr); + } check_radians(cx, expr); } } diff --git a/clippy_lints/src/fn_null_check.rs b/clippy_lints/src/fn_null_check.rs index d8f4a5fe221b..521045a9fed8 100644 --- a/clippy_lints/src/fn_null_check.rs +++ b/clippy_lints/src/fn_null_check.rs @@ -89,11 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for FnNullCheck { // Catching: // (fn_ptr as * ) == - _ if matches!( - constant(cx, cx.typeck_results(), to_check), - Some((Constant::RawPtr(0), _)) - ) => - { + _ if matches!(constant(cx, cx.typeck_results(), to_check), Some(Constant::RawPtr(0))) => { lint_expr(cx, expr); }, diff --git a/clippy_lints/src/format_args.rs b/clippy_lints/src/format_args.rs index 08e45ed7d0ec..d27f5c243664 100644 --- a/clippy_lints/src/format_args.rs +++ b/clippy_lints/src/format_args.rs @@ -14,10 +14,8 @@ use rustc_ast::{ FormatArgPosition, FormatArgPositionKind, FormatArgsPiece, FormatArgumentKind, FormatCount, FormatOptions, FormatPlaceholder, FormatTrait, }; -use rustc_errors::{ - Applicability, - SuggestionStyle::{CompletelyHidden, ShowCode}, -}; +use rustc_errors::Applicability; +use rustc_errors::SuggestionStyle::{CompletelyHidden, ShowCode}; use rustc_hir::{Expr, ExprKind, LangItem}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::adjustment::{Adjust, Adjustment}; diff --git a/clippy_lints/src/format_impl.rs b/clippy_lints/src/format_impl.rs index 3ddee1842a30..66b74d3b5abb 100644 --- a/clippy_lints/src/format_impl.rs +++ b/clippy_lints/src/format_impl.rs @@ -7,8 +7,8 @@ use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, Impl, ImplItem, ImplItemKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::Span; -use rustc_span::{sym, symbol::kw, Symbol}; +use rustc_span::symbol::kw; +use rustc_span::{sym, Span, Symbol}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/format_push_string.rs b/clippy_lints/src/format_push_string.rs index 68c5c3673fe1..45f67020c2db 100644 --- a/clippy_lints/src/format_push_string.rs +++ b/clippy_lints/src/format_push_string.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::ty::is_type_lang_item; -use clippy_utils::{match_def_path, paths, peel_hir_expr_refs}; -use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem}; +use clippy_utils::{higher, match_def_path, paths}; +use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem, MatchSource}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; @@ -44,10 +44,24 @@ fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String) } fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - if let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id { + let e = e.peel_blocks().peel_borrows(); + + if e.span.from_expansion() + && let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id + { cx.tcx.get_diagnostic_name(macro_def_id) == Some(sym::format_macro) + } else if let Some(higher::If { then, r#else, .. }) = higher::If::hir(e) { + is_format(cx, then) || r#else.is_some_and(|e| is_format(cx, e)) } else { - false + match higher::IfLetOrMatch::parse(cx, e) { + Some(higher::IfLetOrMatch::Match(_, arms, MatchSource::Normal)) => { + arms.iter().any(|arm| is_format(cx, arm.body)) + }, + Some(higher::IfLetOrMatch::IfLet(_, _, then, r#else)) => { + is_format(cx, then) ||r#else.is_some_and(|e| is_format(cx, e)) + }, + _ => false, + } } } @@ -68,7 +82,6 @@ impl<'tcx> LateLintPass<'tcx> for FormatPushString { }, _ => return, }; - let (arg, _) = peel_hir_expr_refs(arg); if is_format(cx, arg) { span_lint_and_help( cx, diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 4762b354392b..cf939287940e 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -10,7 +10,19 @@ use rustc_span::source_map::Span; declare_clippy_lint! { /// ### What it does +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + /// Checks for usage of the nonexistent `=*`, `=!` and `=-` +======= /// Checks for usage of the non-existent `=*`, `=!` and `=-` +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + /// Checks for usage of the nonexistent `=*`, `=!` and `=-` +>>>>>>> d2061faf9 (Spelling) +======= + /// Checks for usage of the nonexistent `=*`, `=!` and `=-` +>>>>>>> 4da6e7e06 (rebase attempt) /// operators. /// /// ### Why is this bad? @@ -236,6 +248,12 @@ fn check_else(cx: &EarlyContext<'_>, expr: &Expr) { } } + // Don't warn if the only thing inside post_else_post_eol is a comment block. + let trimmed_post_else_post_eol = post_else_post_eol.trim(); + if trimmed_post_else_post_eol.starts_with("/*") && trimmed_post_else_post_eol.ends_with("*/") { + return + } + let else_desc = if is_if(else_) { "if" } else { "{..}" }; span_lint_and_note( cx, diff --git a/clippy_lints/src/from_over_into.rs b/clippy_lints/src/from_over_into.rs index bd66ace4500a..9584bec40eec 100644 --- a/clippy_lints/src/from_over_into.rs +++ b/clippy_lints/src/from_over_into.rs @@ -10,7 +10,8 @@ use rustc_hir::{ TyKind, }; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::{hir::nested_filter::OnlyBodies, ty}; +use rustc_middle::hir::nested_filter::OnlyBodies; +use rustc_middle::ty; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::{kw, sym}; use rustc_span::{Span, Symbol}; @@ -94,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { ); } - let message = format!("replace the `Into` implentation with `From<{}>`", middle_trait_ref.self_ty()); + let message = format!("replace the `Into` implementation with `From<{}>`", middle_trait_ref.self_ty()); if let Some(suggestions) = convert_to_from(cx, into_trait_seg, target_ty, self_ty, impl_item_ref) { diag.multipart_suggestion(message, suggestions, Applicability::MachineApplicable); } else { @@ -134,9 +135,10 @@ impl<'a, 'tcx> Visitor<'tcx> for SelfFinder<'a, 'tcx> { kw::SelfUpper => self.upper.push(segment.ident.span), _ => continue, } + + self.invalid |= segment.ident.span.from_expansion(); } - self.invalid |= path.span.from_expansion(); if !self.invalid { walk_path(self, path); } @@ -156,6 +158,11 @@ fn convert_to_from( self_ty: &Ty<'_>, impl_item_ref: &ImplItemRef, ) -> Option> { + if !target_ty.find_self_aliases().is_empty() { + // It's tricky to expand self-aliases correctly, we'll ignore it to not cause a + // bad suggestion/fix. + return None; + } let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id); let ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else { return None }; let body = cx.tcx.hir().body(body_id); diff --git a/clippy_lints/src/from_raw_with_void_ptr.rs b/clippy_lints/src/from_raw_with_void_ptr.rs index 096508dc4f11..5e859d97c624 100644 --- a/clippy_lints/src/from_raw_with_void_ptr.rs +++ b/clippy_lints/src/from_raw_with_void_ptr.rs @@ -4,8 +4,7 @@ use clippy_utils::{match_def_path, path_def_id, paths}; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::RawPtr; -use rustc_middle::ty::TypeAndMut; +use rustc_middle::ty::{RawPtr, TypeAndMut}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; diff --git a/clippy_lints/src/functions/impl_trait_in_params.rs b/clippy_lints/src/functions/impl_trait_in_params.rs index d3d0d91c1be7..597fca888851 100644 --- a/clippy_lints/src/functions/impl_trait_in_params.rs +++ b/clippy_lints/src/functions/impl_trait_in_params.rs @@ -1,6 +1,8 @@ -use clippy_utils::{diagnostics::span_lint_and_then, is_in_test_function}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::is_in_test_function; -use rustc_hir::{intravisit::FnKind, Body, HirId}; +use rustc_hir::intravisit::FnKind; +use rustc_hir::{Body, HirId}; use rustc_lint::LateContext; use rustc_span::Span; diff --git a/clippy_lints/src/functions/misnamed_getters.rs b/clippy_lints/src/functions/misnamed_getters.rs index e5945939e60b..169b70f04639 100644 --- a/clippy_lints/src/functions/misnamed_getters.rs +++ b/clippy_lints/src/functions/misnamed_getters.rs @@ -1,7 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; use rustc_errors::Applicability; -use rustc_hir::{intravisit::FnKind, Body, ExprKind, FnDecl, ImplicitSelfKind, Unsafety}; +use rustc_hir::intravisit::FnKind; +use rustc_hir::{Body, ExprKind, FnDecl, ImplicitSelfKind, Unsafety}; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::Span; @@ -40,7 +41,7 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body: }; // Body must be &(mut) .name - // self_data is not neccessarilly self, to also lint sub-getters, etc… + // self_data is not necessarily self, to also lint sub-getters, etc… let block_expr = if_chain! { if let ExprKind::Block(block,_) = body.value.kind; diff --git a/clippy_lints/src/functions/mod.rs b/clippy_lints/src/functions/mod.rs index 7c5e44bb7dca..ee10334c67f1 100644 --- a/clippy_lints/src/functions/mod.rs +++ b/clippy_lints/src/functions/mod.rs @@ -252,6 +252,11 @@ declare_clippy_lint! { /// A `Result` is at least as large as the `Err`-variant. While we /// expect that variant to be seldomly used, the compiler needs to reserve /// and move that much memory every single time. + /// Furthermore, errors are often simply passed up the call-stack, making + /// use of the `?`-operator and its type-conversion mechanics. If the + /// `Err`-variant further up the call-stack stores the `Err`-variant in + /// question (as library code often does), it itself needs to be at least + /// as large, propagating the problem. /// /// ### Known problems /// The size determined by Clippy is platform-dependent. @@ -330,7 +335,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Lints when `impl Trait` is being used in a function's paremeters. + /// Lints when `impl Trait` is being used in a function's parameters. /// ### Why is this bad? /// Turbofish syntax (`::<>`) cannot be used when `impl Trait` is being used, making `impl Trait` less powerful. Readability may also be a factor. /// @@ -348,7 +353,7 @@ declare_clippy_lint! { /// // [...] /// } /// ``` - #[clippy::version = "1.68.0"] + #[clippy::version = "1.69.0"] pub IMPL_TRAIT_IN_PARAMS, restriction, "`impl Trait` is used in the function's parameters" diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index d0ad26282642..c211ca679378 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -1,14 +1,13 @@ use hir::FnSig; use rustc_ast::ast::Attribute; use rustc_errors::Applicability; +use rustc_hir::def::Res; use rustc_hir::def_id::DefIdSet; -use rustc_hir::{self as hir, def::Res, QPath}; +use rustc_hir::{self as hir, QPath}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LintContext}; -use rustc_middle::{ - lint::in_external_macro, - ty::{self, Ty}, -}; +use rustc_middle::lint::in_external_macro; +use rustc_middle::ty::{self, Ty}; use rustc_span::{sym, Span, Symbol}; use clippy_utils::attrs::is_proc_macro; diff --git a/clippy_lints/src/future_not_send.rs b/clippy_lints/src/future_not_send.rs index ed0bd58c770c..5f051e62a389 100644 --- a/clippy_lints/src/future_not_send.rs +++ b/clippy_lints/src/future_not_send.rs @@ -4,7 +4,11 @@ use rustc_hir::intravisit::FnKind; use rustc_hir::{Body, FnDecl}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{self, AliasTy, Clause, EarlyBinder, PredicateKind}; +<<<<<<< HEAD +use rustc_middle::ty::{self, AliasTy, ClauseKind, PredicateKind}; +======= +use rustc_middle::ty::{self, AliasTy, Clause, PredicateKind}; +>>>>>>> e4f5d83fa (Fixed formatting.) use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; use rustc_span::{sym, Span}; @@ -66,9 +70,12 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { if let ty::Alias(ty::Opaque, AliasTy { def_id, substs, .. }) = *ret_ty.kind() { let preds = cx.tcx.explicit_item_bounds(def_id); let mut is_future = false; - for &(p, _span) in preds { - let p = EarlyBinder(p).subst(cx.tcx, substs); + for (p, _span) in preds.subst_iter_copied(cx.tcx, substs) { +<<<<<<< HEAD + if let Some(trait_pred) = p.as_trait_clause() { +======= if let Some(trait_pred) = p.to_opt_poly_trait_pred() { +>>>>>>> e4f5d83fa (Fixed formatting.) if Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() { is_future = true; break; @@ -94,10 +101,10 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { infcx .err_ctxt() .maybe_note_obligation_cause_for_async_await(db, &obligation); - if let PredicateKind::Clause(Clause::Trait(trait_pred)) = + if let PredicateKind::Clause(ClauseKind::Trait(trait_pred)) = obligation.predicate.kind().skip_binder() { - db.note(&format!( + db.note(format!( "`{}` doesn't implement `{}`", trait_pred.self_ty(), trait_pred.trait_ref.print_only_trait_path(), diff --git a/clippy_lints/src/if_let_mutex.rs b/clippy_lints/src/if_let_mutex.rs index 9ea8c494cfcd..e614a8f694fb 100644 --- a/clippy_lints/src/if_let_mutex.rs +++ b/clippy_lints/src/if_let_mutex.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::higher; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::SpanlessEq; +use clippy_utils::{higher, SpanlessEq}; use if_chain::if_chain; use rustc_errors::Diagnostic; use rustc_hir::intravisit::{self as visit, Visitor}; diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index 372b6ead3fe4..a6b035d51062 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -1,9 +1,7 @@ -use clippy_utils::{ - diagnostics::span_lint_hir_and_then, - get_async_fn_body, is_async_fn, - source::{snippet_with_applicability, snippet_with_context, walk_span_to_context}, - visitors::for_each_expr, -}; +use clippy_utils::diagnostics::span_lint_hir_and_then; +use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context}; +use clippy_utils::visitors::for_each_expr; +use clippy_utils::{get_async_fn_body, is_async_fn}; use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; diff --git a/clippy_lints/src/implicit_saturating_add.rs b/clippy_lints/src/implicit_saturating_add.rs index 57e6caa87111..9a43dfbd8874 100644 --- a/clippy_lints/src/implicit_saturating_add.rs +++ b/clippy_lints/src/implicit_saturating_add.rs @@ -101,10 +101,10 @@ fn get_int_max(ty: Ty<'_>) -> Option { fn get_const<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<(u128, BinOpKind, &'tcx Expr<'tcx>)> { if let ExprKind::Binary(op, l, r) = expr.kind { let tr = cx.typeck_results(); - if let Some((Constant::Int(c), _)) = constant(cx, tr, r) { + if let Some(Constant::Int(c)) = constant(cx, tr, r) { return Some((c, op.node, l)); }; - if let Some((Constant::Int(c), _)) = constant(cx, tr, l) { + if let Some(Constant::Int(c)) = constant(cx, tr, l) { return Some((c, invert_op(op.node)?, r)); } } diff --git a/clippy_lints/src/incorrect_impls.rs b/clippy_lints/src/incorrect_impls.rs new file mode 100644 index 000000000000..219b432b2cd7 --- /dev/null +++ b/clippy_lints/src/incorrect_impls.rs @@ -0,0 +1,252 @@ +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::ty::implements_trait; +use clippy_utils::{get_parent_node, is_res_lang_ctor, last_path_segment, path_res}; +use rustc_errors::Applicability; +use rustc_hir::def::Res; +use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, ItemKind, LangItem, Node, UnOp}; +use rustc_hir_analysis::hir_ty_to_ty; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::EarlyBinder; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::sym; +use rustc_span::symbol::kw; + +declare_clippy_lint! { + /// ### What it does + /// Checks for manual implementations of `Clone` when `Copy` is already implemented. + /// + /// ### Why is this bad? + /// If both `Clone` and `Copy` are implemented, they must agree. This is done by dereferencing + /// `self` in `Clone`'s implementation. Anything else is incorrect. + /// + /// ### Example + /// ```rust,ignore + /// #[derive(Eq, PartialEq)] + /// struct A(u32); + /// + /// impl Clone for A { + /// fn clone(&self) -> Self { + /// Self(self.0) + /// } + /// } + /// + /// impl Copy for A {} + /// ``` + /// Use instead: + /// ```rust,ignore + /// #[derive(Eq, PartialEq)] + /// struct A(u32); + /// + /// impl Clone for A { + /// fn clone(&self) -> Self { + /// *self + /// } + /// } + /// + /// impl Copy for A {} + /// ``` + #[clippy::version = "1.72.0"] + pub INCORRECT_CLONE_IMPL_ON_COPY_TYPE, + correctness, + "manual implementation of `Clone` on a `Copy` type" +} +declare_clippy_lint! { + /// ### What it does + /// Checks for manual implementations of both `PartialOrd` and `Ord` when only `Ord` is + /// necessary. + /// + /// ### Why is this bad? + /// If both `PartialOrd` and `Ord` are implemented, they must agree. This is commonly done by + /// wrapping the result of `cmp` in `Some` for `partial_cmp`. Not doing this may silently + /// introduce an error upon refactoring. + /// + /// ### Limitations + /// Will not lint if `Self` and `Rhs` do not have the same type. + /// + /// ### Example + /// ```rust + /// # use std::cmp::Ordering; + /// #[derive(Eq, PartialEq)] + /// struct A(u32); + /// + /// impl Ord for A { + /// fn cmp(&self, other: &Self) -> Ordering { + /// // ... + /// # todo!(); + /// } + /// } + /// + /// impl PartialOrd for A { + /// fn partial_cmp(&self, other: &Self) -> Option { + /// // ... + /// # todo!(); + /// } + /// } + /// ``` + /// Use instead: + /// ```rust + /// # use std::cmp::Ordering; + /// #[derive(Eq, PartialEq)] + /// struct A(u32); + /// + /// impl Ord for A { + /// fn cmp(&self, other: &Self) -> Ordering { + /// // ... + /// # todo!(); + /// } + /// } + /// + /// impl PartialOrd for A { + /// fn partial_cmp(&self, other: &Self) -> Option { + /// Some(self.cmp(other)) + /// } + /// } + /// ``` + #[clippy::version = "1.72.0"] + pub INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE, + correctness, + "manual implementation of `PartialOrd` when `Ord` is already implemented" +} +declare_lint_pass!(IncorrectImpls => [INCORRECT_CLONE_IMPL_ON_COPY_TYPE, INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE]); + +impl LateLintPass<'_> for IncorrectImpls { + #[expect(clippy::too_many_lines)] + fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) { + let Some(Node::Item(item)) = get_parent_node(cx.tcx, impl_item.hir_id()) else { + return; + }; + let Some(trait_impl) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::skip_binder) else { + return; + }; + if cx.tcx.is_automatically_derived(item.owner_id.to_def_id()) { + return; + } + let ItemKind::Impl(imp) = item.kind else { + return; + }; + let ImplItemKind::Fn(_, impl_item_id) = cx.tcx.hir().impl_item(impl_item.impl_item_id()).kind else { + return; + }; + let body = cx.tcx.hir().body(impl_item_id); + let ExprKind::Block(block, ..) = body.value.kind else { + return; + }; + + if cx.tcx.is_diagnostic_item(sym::Clone, trait_impl.def_id) + && let Some(copy_def_id) = cx.tcx.get_diagnostic_item(sym::Copy) + && implements_trait( + cx, + trait_impl.self_ty(), + copy_def_id, +<<<<<<< HEAD +<<<<<<< HEAD + &[], +======= + trait_impl.substs, +>>>>>>> 10cc1684c (rename lint and disallow `clone_from`) +======= + &[], +>>>>>>> 5df1f6681 (Pass correct substs to `implements_trait` in `incorrect_impls`) + ) + { + if impl_item.ident.name == sym::clone { + if block.stmts.is_empty() + && let Some(expr) = block.expr + && let ExprKind::Unary(UnOp::Deref, deref) = expr.kind + && let ExprKind::Path(qpath) = deref.kind + && last_path_segment(&qpath).ident.name == kw::SelfLower + {} else { + span_lint_and_sugg( + cx, + INCORRECT_CLONE_IMPL_ON_COPY_TYPE, + block.span, + "incorrect implementation of `clone` on a `Copy` type", + "change this to", + "{ *self }".to_owned(), + Applicability::MaybeIncorrect, + ); + + return; + } + } + + if impl_item.ident.name == sym::clone_from { + span_lint_and_sugg( + cx, + INCORRECT_CLONE_IMPL_ON_COPY_TYPE, + impl_item.span, + "incorrect implementation of `clone_from` on a `Copy` type", + "remove it", + String::new(), + Applicability::MaybeIncorrect, + ); + + return; + } + } + + if cx.tcx.is_diagnostic_item(sym::PartialOrd, trait_impl.def_id) + && impl_item.ident.name == sym::partial_cmp + && let Some(ord_def_id) = cx + .tcx + .diagnostic_items(trait_impl.def_id.krate) + .name_to_id + .get(&sym::Ord) + && implements_trait( + cx, + hir_ty_to_ty(cx.tcx, imp.self_ty), + *ord_def_id, + trait_impl.substs, + ) + { + if block.stmts.is_empty() + && let Some(expr) = block.expr + && let ExprKind::Call( + Expr { + kind: ExprKind::Path(some_path), + hir_id: some_hir_id, + .. + }, + [cmp_expr], + ) = expr.kind + && is_res_lang_ctor(cx, cx.qpath_res(some_path, *some_hir_id), LangItem::OptionSome) + && let ExprKind::MethodCall(cmp_path, _, [other_expr], ..) = cmp_expr.kind + && cmp_path.ident.name == sym::cmp + && let Res::Local(..) = path_res(cx, other_expr) + {} else { + // If `Self` and `Rhs` are not the same type, bail. This makes creating a valid + // suggestion tons more complex. + if let [lhs, rhs, ..] = trait_impl.substs.as_slice() && lhs != rhs { + return; + } + + span_lint_and_then( + cx, + INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE, + item.span, + "incorrect implementation of `partial_cmp` on an `Ord` type", + |diag| { + let [_, other] = body.params else { + return; + }; + + let suggs = if let Some(other_ident) = other.pat.simple_ident() { + vec![(block.span, format!("{{ Some(self.cmp({})) }}", other_ident.name))] + } else { + vec![ + (block.span, "{ Some(self.cmp(other)) }".to_owned()), + (other.pat.span, "other".to_owned()), + ] + }; + + diag.multipart_suggestion( + "change this to", + suggs, + Applicability::Unspecified, + ); + } + ); + } + } + } +} diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs index bdeddf44df7b..01a7c497cbe7 100644 --- a/clippy_lints/src/index_refutable_slice.rs +++ b/clippy_lints/src/index_refutable_slice.rs @@ -13,7 +13,8 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::ty; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{symbol::Ident, Span}; +use rustc_span::symbol::Ident; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does @@ -254,7 +255,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> { let parent_id = map.parent_id(expr.hir_id); if let Some(hir::Node::Expr(parent_expr)) = map.find(parent_id); if let hir::ExprKind::Index(_, index_expr) = parent_expr.kind; - if let Some((Constant::Int(index_value), _)) = constant(cx, cx.typeck_results(), index_expr); + if let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr); if let Ok(index_value) = index_value.try_into(); if index_value < max_suggested_slice; diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs index c384172fbde8..22c14d9b04dd 100644 --- a/clippy_lints/src/indexing_slicing.rs +++ b/clippy_lints/src/indexing_slicing.rs @@ -170,7 +170,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { return; } // Index is a constant uint. - if let Some(..) = constant(cx, cx.typeck_results(), index) { + if constant(cx, cx.typeck_results(), index).is_some() { // Let rustc's `const_err` lint handle constant `usize` indexing on arrays. return; } @@ -191,18 +191,14 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { /// Returns a tuple of options with the start and end (exclusive) values of /// the range. If the start or end is not constant, None is returned. fn to_const_range(cx: &LateContext<'_>, range: higher::Range<'_>, array_size: u128) -> (Option, Option) { - let s = range - .start - .map(|expr| constant(cx, cx.typeck_results(), expr).map(|(c, _)| c)); + let s = range.start.map(|expr| constant(cx, cx.typeck_results(), expr)); let start = match s { Some(Some(Constant::Int(x))) => Some(x), Some(_) => None, None => Some(0), }; - let e = range - .end - .map(|expr| constant(cx, cx.typeck_results(), expr).map(|(c, _)| c)); + let e = range.end.map(|expr| constant(cx, cx.typeck_results(), expr)); let end = match e { Some(Some(Constant::Int(x))) => { if range.limits == RangeLimits::Closed { diff --git a/clippy_lints/src/inherent_impl.rs b/clippy_lints/src/inherent_impl.rs index 7c41699f307a..77e541d5b167 100644 --- a/clippy_lints/src/inherent_impl.rs +++ b/clippy_lints/src/inherent_impl.rs @@ -3,7 +3,8 @@ use clippy_utils::diagnostics::span_lint_and_note; use clippy_utils::is_lint_allowed; use rustc_data_structures::fx::FxHashMap; -use rustc_hir::{def_id::LocalDefId, Item, ItemKind, Node}; +use rustc_hir::def_id::LocalDefId; +use rustc_hir::{Item, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::Span; diff --git a/clippy_lints/src/init_numbered_fields.rs b/clippy_lints/src/init_numbered_fields.rs index 7e1548531f10..f95d2c2edb1e 100644 --- a/clippy_lints/src/init_numbered_fields.rs +++ b/clippy_lints/src/init_numbered_fields.rs @@ -71,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for NumberedFields { INIT_NUMBERED_FIELDS, e.span, "used a field initializer for a tuple struct", - "try this instead", + "try", snippet, appl, ); diff --git a/clippy_lints/src/instant_subtraction.rs b/clippy_lints/src/instant_subtraction.rs index 34e9991582c0..8df7dfb8b9e5 100644 --- a/clippy_lints/src/instant_subtraction.rs +++ b/clippy_lints/src/instant_subtraction.rs @@ -7,7 +7,8 @@ use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{source_map::Spanned, sym}; +use rustc_span::source_map::Spanned; +use rustc_span::sym; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/invalid_utf8_in_unchecked.rs b/clippy_lints/src/invalid_utf8_in_unchecked.rs deleted file mode 100644 index 6a4861747d26..000000000000 --- a/clippy_lints/src/invalid_utf8_in_unchecked.rs +++ /dev/null @@ -1,74 +0,0 @@ -use clippy_utils::diagnostics::span_lint; -use clippy_utils::{match_function_call, paths}; -use rustc_ast::{BorrowKind, LitKind}; -use rustc_hir::{Expr, ExprKind}; -use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Spanned; -use rustc_span::Span; - -declare_clippy_lint! { - /// ### What it does - /// Checks for `std::str::from_utf8_unchecked` with an invalid UTF-8 literal - /// - /// ### Why is this bad? - /// Creating such a `str` would result in undefined behavior - /// - /// ### Example - /// ```rust - /// # #[allow(unused)] - /// unsafe { - /// std::str::from_utf8_unchecked(b"cl\x82ippy"); - /// } - /// ``` - #[clippy::version = "1.64.0"] - pub INVALID_UTF8_IN_UNCHECKED, - correctness, - "using a non UTF-8 literal in `std::std::from_utf8_unchecked`" -} -declare_lint_pass!(InvalidUtf8InUnchecked => [INVALID_UTF8_IN_UNCHECKED]); - -impl<'tcx> LateLintPass<'tcx> for InvalidUtf8InUnchecked { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { - if let Some([arg]) = match_function_call(cx, expr, &paths::STR_FROM_UTF8_UNCHECKED) { - match &arg.kind { - ExprKind::Lit(Spanned { node: lit, .. }) => { - if let LitKind::ByteStr(bytes, _) = &lit - && std::str::from_utf8(bytes).is_err() - { - lint(cx, expr.span); - } - }, - ExprKind::AddrOf(BorrowKind::Ref, _, Expr { kind: ExprKind::Array(args), .. }) => { - let elements = args.iter().map(|e|{ - match &e.kind { - ExprKind::Lit(Spanned { node: lit, .. }) => match lit { - LitKind::Byte(b) => Some(*b), - #[allow(clippy::cast_possible_truncation)] - LitKind::Int(b, _) => Some(*b as u8), - _ => None - } - _ => None - } - }).collect::>>(); - - if let Some(elements) = elements - && std::str::from_utf8(&elements).is_err() - { - lint(cx, expr.span); - } - } - _ => {} - } - } - } -} - -fn lint(cx: &LateContext<'_>, span: Span) { - span_lint( - cx, - INVALID_UTF8_IN_UNCHECKED, - span, - "non UTF-8 literal in `std::str::from_utf8_unchecked`", - ); -} diff --git a/clippy_lints/src/items_after_test_module.rs b/clippy_lints/src/items_after_test_module.rs new file mode 100644 index 000000000000..994925bfd269 --- /dev/null +++ b/clippy_lints/src/items_after_test_module.rs @@ -0,0 +1,371 @@ +<<<<<<< HEAD +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::{is_from_proc_macro, is_in_cfg_test}; +======= +use clippy_utils::{diagnostics::span_lint_and_help, is_in_cfg_test}; +>>>>>>> e4f5d83fa (Fixed formatting.) +use rustc_hir::{HirId, ItemId, ItemKind, Mod}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +use rustc_span::{sym, Span}; +======= +======= +use rustc_span::{sym, Span}; +======= +<<<<<<< HEAD +<<<<<<< HEAD +use rustc_span::{sym, Span}; +======= +>>>>>>> 4da6e7e06 (rebase attempt) +use rustc_span::sym; +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= +use rustc_span::{sym, Span}; +>>>>>>> 1ac8dc51b (Compact emmited lint) +<<<<<<< HEAD +======= +use rustc_span::{sym, Span}; +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +use rustc_span::sym; +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= +use rustc_span::{sym, Span}; +>>>>>>> 1ac8dc51b (Compact emmited lint) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + +declare_clippy_lint! { + /// ### What it does + /// Triggers if an item is declared after the testing module marked with `#[cfg(test)]`. + /// ### Why is this bad? + /// Having items declared after the testing module is confusing and may lead to bad test coverage. + /// ### Example + /// ```rust + /// #[cfg(test)] + /// mod tests { + /// // [...] + /// } + /// + /// fn my_function() { + /// // [...] + /// } + /// ``` + /// Use instead: + /// ```rust + /// fn my_function() { + /// // [...] + /// } + /// + /// #[cfg(test)] + /// mod tests { + /// // [...] + /// } + /// ``` +<<<<<<< HEAD + #[clippy::version = "1.71.0"] +======= + #[clippy::version = "1.70.0"] +>>>>>>> e4f5d83fa (Fixed formatting.) + pub ITEMS_AFTER_TEST_MODULE, + style, + "An item was found after the testing module `tests`" +} + +declare_lint_pass!(ItemsAfterTestModule => [ITEMS_AFTER_TEST_MODULE]); + +impl LateLintPass<'_> for ItemsAfterTestModule { + fn check_mod(&mut self, cx: &LateContext<'_>, _: &Mod<'_>, _: HirId) { + let mut was_test_mod_visited = false; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + let mut test_mod_span: Option = None; +======= +======= + let mut test_mod_span: Option = None; +======= +<<<<<<< HEAD +<<<<<<< HEAD + let mut test_mod_span: Option = None; +======= +>>>>>>> 4da6e7e06 (rebase attempt) + let mut test_mod_hash: Option = None; +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= + let mut test_mod_span: Option = None; +>>>>>>> 1ac8dc51b (Compact emmited lint) +<<<<<<< HEAD +======= + let mut test_mod_span: Option = None; +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + let mut test_mod_hash: Option = None; +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= + let mut test_mod_span: Option = None; +>>>>>>> 1ac8dc51b (Compact emmited lint) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + + let hir = cx.tcx.hir(); + let items = hir.items().collect::>(); + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + for (i, itid) in items.iter().enumerate() { +======= +======= + for (i, itid) in items.iter().enumerate() { +======= +<<<<<<< HEAD +<<<<<<< HEAD + for (i, itid) in items.iter().enumerate() { +======= +>>>>>>> 4da6e7e06 (rebase attempt) + for itid in &items { +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= + for (i, itid) in items.iter().enumerate() { +>>>>>>> 1ac8dc51b (Compact emmited lint) +<<<<<<< HEAD +======= + for (i, itid) in items.iter().enumerate() { +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + for itid in &items { +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= + for (i, itid) in items.iter().enumerate() { +>>>>>>> 1ac8dc51b (Compact emmited lint) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + let item = hir.item(*itid); + + if_chain! { + if was_test_mod_visited; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +======= +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + if i == (items.len() - 3 /* Weird magic number (HIR-translation behaviour) */); + if cx.sess().source_map().lookup_char_pos(item.span.lo()).file.name_hash + == cx.sess().source_map().lookup_char_pos(test_mod_span.unwrap().lo()).file.name_hash; // Will never fail + if !matches!(item.kind, ItemKind::Mod(_)); + if !is_in_cfg_test(cx.tcx, itid.hir_id()); // The item isn't in the testing module itself + if !in_external_macro(cx.sess(), item.span); +<<<<<<< HEAD + if !is_from_proc_macro(cx, item); + + then { + span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, test_mod_span.unwrap().with_hi(item.span.hi()), "items were found after the testing module", None, "move the items to before the testing module was defined"); +<<<<<<< HEAD +======= +======= + if i == (items.len() - 3 /* Weird magic number (HIR-translation behaviour) */); +>>>>>>> 1ac8dc51b (Compact emmited lint) + if cx.sess().source_map().lookup_char_pos(item.span.lo()).file.name_hash + == cx.sess().source_map().lookup_char_pos(test_mod_span.unwrap().lo()).file.name_hash; // Will never fail + if !matches!(item.kind, ItemKind::Mod(_)); + if !is_in_cfg_test(cx.tcx, itid.hir_id()); // The item isn't in the testing module itself + if !in_external_macro(cx.sess(), item.span); + + then { +<<<<<<< HEAD + span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, item.span, "an item was found after the testing module", None, "move the item to before the testing module was defined"); +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= + span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, test_mod_span.unwrap().with_hi(item.span.hi()), "items were found after the testing module", None, "move the items to before the testing module was defined"); +>>>>>>> 1ac8dc51b (Compact emmited lint) + }}; + +<<<<<<< HEAD +======= +======= + + then { + span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, test_mod_span.unwrap().with_hi(item.span.hi()), "items were found after the testing module", None, "move the items to before the testing module was defined"); +======= +======= + if i == (items.len() - 3 /* Weird magic number (HIR-translation behaviour) */); +>>>>>>> 1ac8dc51b (Compact emmited lint) + if cx.sess().source_map().lookup_char_pos(item.span.lo()).file.name_hash + == cx.sess().source_map().lookup_char_pos(test_mod_span.unwrap().lo()).file.name_hash; // Will never fail + if !matches!(item.kind, ItemKind::Mod(_)); + if !is_in_cfg_test(cx.tcx, itid.hir_id()); // The item isn't in the testing module itself + if !in_external_macro(cx.sess(), item.span); + + then { +<<<<<<< HEAD + span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, item.span, "an item was found after the testing module", None, "move the item to before the testing module was defined"); +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= + span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, test_mod_span.unwrap().with_hi(item.span.hi()), "items were found after the testing module", None, "move the items to before the testing module was defined"); +>>>>>>> 1ac8dc51b (Compact emmited lint) + }}; + +>>>>>>> 4da6e7e06 (rebase attempt) +<<<<<<< HEAD + if matches!(item.kind, ItemKind::Mod(_)) { + for attr in cx.tcx.get_attrs(item.owner_id.to_def_id(), sym::cfg) { + if_chain! { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 1ac8dc51b (Compact emmited lint) + if attr.has_name(sym::cfg); +======= +<<<<<<< HEAD +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + if let ItemKind::Mod(module) = item.kind && item.span.hi() == module.spans.inner_span.hi() { + // Check that it works the same way, the only I way I've found for #10713 + for attr in cx.tcx.get_attrs(item.owner_id.to_def_id(), sym::cfg) { + if_chain! { + if attr.has_name(sym::cfg); +<<<<<<< HEAD +>>>>>>> 273c898ae (Fix #10713 and move the tests to a subdir) +======= +======= +======= + if i == (items.len() - 3 /* Weird magic number (HIR-translation behaviour) */); +>>>>>>> 1ac8dc51b (Compact emmited lint) + if cx.sess().source_map().lookup_char_pos(item.span.lo()).file.name_hash + == cx.sess().source_map().lookup_char_pos(test_mod_span.unwrap().lo()).file.name_hash; // Will never fail + if !matches!(item.kind, ItemKind::Mod(_)); + if !is_in_cfg_test(cx.tcx, itid.hir_id()); // The item isn't in the testing module itself + if !in_external_macro(cx.sess(), item.span); + + then { +<<<<<<< HEAD + span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, item.span, "an item was found after the testing module", None, "move the item to before the testing module was defined"); +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= + span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, test_mod_span.unwrap().with_hi(item.span.hi()), "items were found after the testing module", None, "move the items to before the testing module was defined"); +>>>>>>> 1ac8dc51b (Compact emmited lint) + }}; + +<<<<<<< HEAD + if matches!(item.kind, ItemKind::Mod(_)) { + for attr in cx.tcx.get_attrs(item.owner_id.to_def_id(), sym::cfg) { + if_chain! { +<<<<<<< HEAD +<<<<<<< HEAD + if attr.has_name(sym::cfg); +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + if attr.has_name(sym::cfg); +>>>>>>> 1ac8dc51b (Compact emmited lint) +======= + if let ItemKind::Mod(module) = item.kind && item.span.hi() == module.spans.inner_span.hi() { + // Check that it works the same way, the only I way I've found for #10713 + for attr in cx.tcx.get_attrs(item.owner_id.to_def_id(), sym::cfg) { + if_chain! { + if attr.has_name(sym::cfg); +>>>>>>> 273c898ae (Fix #10713 and move the tests to a subdir) +======= +<<<<<<< HEAD +======= +>>>>>>> 273c898ae (Fix #10713 and move the tests to a subdir) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + if let Some(mitems) = attr.meta_item_list(); + if let [mitem] = &*mitems; + if mitem.has_name(sym::test); + then { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + was_test_mod_visited = true; + test_mod_span = Some(item.span); + } + } +<<<<<<< HEAD +======= +======= +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) + if attr.has_name(sym::cfg); + if let Some(mitems) = attr.meta_item_list(); + if let [mitem] = &*mitems; + if mitem.has_name(sym::test); + then { + was_test_mod_visited = true; + test_mod_hash = Some(cx.sess().source_map().lookup_char_pos(item.span.lo()).file.name_hash); + } + } +<<<<<<< HEAD +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= +>>>>>>> 1ac8dc51b (Compact emmited lint) + } + } +======= +======= +>>>>>>> 1ac8dc51b (Compact emmited lint) + was_test_mod_visited = true; + test_mod_span = Some(item.span); + } + } + } + } +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + } + } +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= + was_test_mod_visited = true; + test_mod_span = Some(item.span); + } + } +<<<<<<< HEAD +======= +<<<<<<< HEAD +======= + if attr.has_name(sym::cfg); + if let Some(mitems) = attr.meta_item_list(); + if let [mitem] = &*mitems; + if mitem.has_name(sym::test); + then { + was_test_mod_visited = true; + test_mod_hash = Some(cx.sess().source_map().lookup_char_pos(item.span.lo()).file.name_hash); + } + } +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= +>>>>>>> 1ac8dc51b (Compact emmited lint) +>>>>>>> e4f5d83fa (Fixed formatting.) + } + } +>>>>>>> 273c898ae (Fix #10713 and move the tests to a subdir) + } + } +} diff --git a/clippy_lints/src/iter_not_returning_iterator.rs b/clippy_lints/src/iter_not_returning_iterator.rs index c924d7361ce3..c16717deee07 100644 --- a/clippy_lints/src/iter_not_returning_iterator.rs +++ b/clippy_lints/src/iter_not_returning_iterator.rs @@ -1,5 +1,8 @@ -use clippy_utils::{diagnostics::span_lint, get_parent_node, ty::implements_trait}; -use rustc_hir::{def_id::LocalDefId, FnSig, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind}; +use clippy_utils::diagnostics::span_lint; +use clippy_utils::get_parent_node; +use clippy_utils::ty::implements_trait; +use rustc_hir::def_id::LocalDefId; +use rustc_hir::{FnSig, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs index 1c99bd2f3d02..9caaec4e5ccf 100644 --- a/clippy_lints/src/large_enum_variant.rs +++ b/clippy_lints/src/large_enum_variant.rs @@ -1,10 +1,8 @@ //! lint when there is a large size difference between variants on an enum +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::{ - diagnostics::span_lint_and_then, - ty::{approx_ty_size, is_copy, AdtVariantInfo}, -}; +use clippy_utils::ty::{approx_ty_size, is_copy, AdtVariantInfo}; use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; diff --git a/clippy_lints/src/large_futures.rs b/clippy_lints/src/large_futures.rs index 1b0544813718..6bb2b632db3c 100644 --- a/clippy_lints/src/large_futures.rs +++ b/clippy_lints/src/large_futures.rs @@ -1,5 +1,6 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; -use clippy_utils::{diagnostics::span_lint_and_sugg, ty::implements_trait}; +use clippy_utils::ty::implements_trait; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, LangItem, MatchSource, QPath}; use rustc_lint::{LateContext, LateLintPass}; @@ -11,7 +12,15 @@ declare_clippy_lint! { /// It checks for the size of a `Future` created by `async fn` or `async {}`. /// /// ### Why is this bad? +<<<<<<< HEAD +<<<<<<< HEAD + /// Due to the current [unideal implementation](https://github.com/rust-lang/rust/issues/69826) of `Generator`, +======= /// Due to the current [unideal implemention](https://github.com/rust-lang/rust/issues/69826) of `Generator`, +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + /// Due to the current [unideal implementation](https://github.com/rust-lang/rust/issues/69826) of `Generator`, +>>>>>>> d2061faf9 (Spelling) /// large size of a `Future` may cause stack overflows. /// /// ### Example @@ -38,7 +47,7 @@ declare_clippy_lint! { /// wait(fut).await; /// } /// ``` - #[clippy::version = "1.68.0"] + #[clippy::version = "1.70.0"] pub LARGE_FUTURES, pedantic, "large future may lead to unexpected stack overflows" diff --git a/clippy_lints/src/large_include_file.rs b/clippy_lints/src/large_include_file.rs index 424c0d9e7982..566901de3475 100644 --- a/clippy_lints/src/large_include_file.rs +++ b/clippy_lints/src/large_include_file.rs @@ -2,8 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_note; use clippy_utils::is_lint_allowed; use clippy_utils::macros::root_macro_call_first_node; use rustc_ast::LitKind; -use rustc_hir::Expr; -use rustc_hir::ExprKind; +use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::sym; diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index 32c6312e0694..0a5901bce046 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -38,7 +38,7 @@ impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]); impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - if let ExprKind::Repeat(_, _) = expr.kind + if let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() && let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind() && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) diff --git a/clippy_lints/src/large_stack_frames.rs b/clippy_lints/src/large_stack_frames.rs new file mode 100644 index 000000000000..25b293cf0438 --- /dev/null +++ b/clippy_lints/src/large_stack_frames.rs @@ -0,0 +1,239 @@ +use std::ops::AddAssign; + +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::diagnostics::span_lint_and_note; +use clippy_utils::fn_has_unsatisfiable_preds; +<<<<<<< HEAD +======= +use clippy_utils::diagnostics::span_lint_and_then; +>>>>>>> 7312a93a0 (new lint: `large_stack_frames`) +======= +use clippy_utils::diagnostics::span_lint_and_note; +>>>>>>> 6b232fdee (use span_lint_and_note) +======= +>>>>>>> de7d43bc6 (make lint description easier to read, prevent ICE) +use rustc_hir::def_id::LocalDefId; +use rustc_hir::intravisit::FnKind; +use rustc_hir::{Body, FnDecl}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::Span; + +declare_clippy_lint! { + /// ### What it does + /// Checks for functions that use a lot of stack space. + /// + /// This often happens when constructing a large type, such as an array with a lot of elements, + /// or constructing *many* smaller-but-still-large structs, or copying around a lot of large types. + /// + /// This lint is a more general version of [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/#large_stack_arrays) + /// that is intended to look at functions as a whole instead of only individual array expressions inside of a function. + /// + /// ### Why is this bad? + /// The stack region of memory is very limited in size (usually *much* smaller than the heap) and attempting to + /// use too much will result in a stack overflow and crash the program. + /// To avoid this, you should consider allocating large types on the heap instead (e.g. by boxing them). + /// + /// Keep in mind that the code path to construction of large types does not even need to be reachable; + /// it purely needs to *exist* inside of the function to contribute to the stack size. +<<<<<<< HEAD +<<<<<<< HEAD + /// For example, this causes a stack overflow even though the branch is unreachable: +======= + /// For example, this causes a stack overflow even though the branch is unreachable (with `-Zmir-opt-level=0`): +>>>>>>> 7312a93a0 (new lint: `large_stack_frames`) +======= + /// For example, this causes a stack overflow even though the branch is unreachable: +>>>>>>> de7d43bc6 (make lint description easier to read, prevent ICE) + /// ```rust,ignore + /// fn main() { + /// if false { + /// let x = [0u8; 10000000]; // 10 MB stack array + /// black_box(&x); + /// } + /// } + /// ``` + /// +<<<<<<< HEAD +<<<<<<< HEAD + /// ### Known issues +======= + /// ### Drawbacks +>>>>>>> 7312a93a0 (new lint: `large_stack_frames`) +======= + /// ### Known issues +>>>>>>> 7aa4babb5 (rename "drawbacks" to "known issues") + /// False positives. The stack size that clippy sees is an estimated value and can be vastly different + /// from the actual stack usage after optimizations passes have run (especially true in release mode). + /// Modern compilers are very smart and are able to optimize away a lot of unnecessary stack allocations. + /// In debug mode however, it is usually more accurate. + /// +<<<<<<< HEAD +<<<<<<< HEAD + /// This lint works by summing up the size of all variables that the user typed, variables that were + /// implicitly introduced by the compiler for temporaries, function arguments and the return value, + /// and comparing them against a (configurable, but high-by-default). +======= + /// This lint works by summing up the size of all locals and comparing them against a (configurable, but high-by-default) + /// threshold. + /// Note that "locals" in this context refers to [MIR locals](https://rustc-dev-guide.rust-lang.org/mir/index.html#key-mir-vocabulary), + /// i.e. real local variables that the user typed, storage for temporary values, function arguments + /// and the return value. +>>>>>>> 7312a93a0 (new lint: `large_stack_frames`) +======= + /// This lint works by summing up the size of all variables that the user typed, variables that were + /// implicitly introduced by the compiler for temporaries, function arguments and the return value, + /// and comparing them against a (configurable, but high-by-default). +>>>>>>> de7d43bc6 (make lint description easier to read, prevent ICE) + /// + /// ### Example + /// This function creates four 500 KB arrays on the stack. Quite big but just small enough to not trigger `large_stack_arrays`. + /// However, looking at the function as a whole, it's clear that this uses a lot of stack space. + /// ```rust + /// struct QuiteLargeType([u8; 500_000]); + /// fn foo() { + /// // ... some function that uses a lot of stack space ... + /// let _x1 = QuiteLargeType([0; 500_000]); + /// let _x2 = QuiteLargeType([0; 500_000]); + /// let _x3 = QuiteLargeType([0; 500_000]); + /// let _x4 = QuiteLargeType([0; 500_000]); + /// } + /// ``` + /// + /// Instead of doing this, allocate the arrays on the heap. + /// This currently requires going through a `Vec` first and then converting it to a `Box`: + /// ```rust + /// struct NotSoLargeType(Box<[u8]>); + /// + /// fn foo() { + /// let _x1 = NotSoLargeType(vec![0; 500_000].into_boxed_slice()); + /// // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Now heap allocated. + /// // The size of `NotSoLargeType` is 16 bytes. + /// // ... + /// } + /// ``` + #[clippy::version = "1.71.0"] + pub LARGE_STACK_FRAMES, + nursery, + "checks for functions that allocate a lot of stack space" +} + +pub struct LargeStackFrames { + maximum_allowed_size: u64, +} + +impl LargeStackFrames { + #[must_use] + pub fn new(size: u64) -> Self { + Self { + maximum_allowed_size: size, + } + } +} + +impl_lint_pass!(LargeStackFrames => [LARGE_STACK_FRAMES]); + +#[derive(Copy, Clone)] +enum Space { + Used(u64), + Overflow, +} + +impl Space { + pub fn exceeds_limit(self, limit: u64) -> bool { + match self { + Self::Used(used) => used > limit, + Self::Overflow => true, + } + } +} + +impl AddAssign for Space { + fn add_assign(&mut self, rhs: u64) { + if let Self::Used(lhs) = self { + match lhs.checked_add(rhs) { + Some(sum) => *self = Self::Used(sum), +<<<<<<< HEAD +<<<<<<< HEAD + None => *self = Self::Overflow, +======= + None => { + *self = Self::Overflow; + }, +>>>>>>> 7312a93a0 (new lint: `large_stack_frames`) +======= + None => *self = Self::Overflow, +>>>>>>> 52c6ef77f (fmt) + } + } + } +} + +impl<'tcx> LateLintPass<'tcx> for LargeStackFrames { + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + _: FnKind<'tcx>, + _: &'tcx FnDecl<'tcx>, + _: &'tcx Body<'tcx>, + span: Span, + local_def_id: LocalDefId, + ) { + let def_id = local_def_id.to_def_id(); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> de7d43bc6 (make lint description easier to read, prevent ICE) + // Building MIR for `fn`s with unsatisfiable preds results in ICE. + if fn_has_unsatisfiable_preds(cx, def_id) { + return; + } +<<<<<<< HEAD +======= +>>>>>>> 7312a93a0 (new lint: `large_stack_frames`) +======= +>>>>>>> de7d43bc6 (make lint description easier to read, prevent ICE) + + let mir = cx.tcx.optimized_mir(def_id); + let param_env = cx.tcx.param_env(def_id); + + let mut frame_size = Space::Used(0); + + for local in &mir.local_decls { + if let Ok(layout) = cx.tcx.layout_of(param_env.and(local.ty)) { + frame_size += layout.size.bytes(); + } + } + + if frame_size.exceeds_limit(self.maximum_allowed_size) { +<<<<<<< HEAD +<<<<<<< HEAD + span_lint_and_note( +======= + span_lint_and_then( +>>>>>>> 7312a93a0 (new lint: `large_stack_frames`) +======= + span_lint_and_note( +>>>>>>> 6b232fdee (use span_lint_and_note) + cx, + LARGE_STACK_FRAMES, + span, + "this function allocates a large amount of stack space", +<<<<<<< HEAD +<<<<<<< HEAD + None, + "allocating large amounts of stack space can overflow the stack", +======= + |diag| { + diag.note("allocating large amounts of stack space can overflow the stack"); + }, +>>>>>>> 7312a93a0 (new lint: `large_stack_frames`) +======= + None, + "allocating large amounts of stack space can overflow the stack", +>>>>>>> 6b232fdee (use span_lint_and_note) + ); + } + } +} diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 0805b4b19796..a4e24e36ff02 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -1,22 +1,23 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; use clippy_utils::source::snippet_with_context; -use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators, sugg::Sugg}; +use clippy_utils::sugg::Sugg; +use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators}; use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::def_id::DefIdSet; +use rustc_hir::def::Res; +use rustc_hir::def_id::{DefId, DefIdSet}; +use rustc_hir::lang_items::LangItem; use rustc_hir::{ - def::Res, def_id::DefId, lang_items::LangItem, AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, - GenericBound, ImplItem, ImplItemKind, ImplicitSelfKind, Item, ItemKind, Mutability, Node, PathSegment, PrimTy, - QPath, TraitItemRef, TyKind, TypeBindingKind, + AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind, + ImplicitSelfKind, Item, ItemKind, Mutability, Node, PathSegment, PrimTy, QPath, TraitItemRef, TyKind, + TypeBindingKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, AssocKind, FnSig, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::{ - source_map::{Span, Spanned, Symbol}, - symbol::sym, -}; +use rustc_span::source_map::{Span, Spanned, Symbol}; +use rustc_span::symbol::sym; declare_clippy_lint! { /// ### What it does @@ -168,25 +169,27 @@ impl<'tcx> LateLintPass<'tcx> for LenZero { } if let ExprKind::Binary(Spanned { node: cmp, .. }, left, right) = expr.kind { + // expr.span might contains parenthesis, see issue #10529 + let actual_span = left.span.with_hi(right.span.hi()); match cmp { BinOpKind::Eq => { - check_cmp(cx, expr.span, left, right, "", 0); // len == 0 - check_cmp(cx, expr.span, right, left, "", 0); // 0 == len + check_cmp(cx, actual_span, left, right, "", 0); // len == 0 + check_cmp(cx, actual_span, right, left, "", 0); // 0 == len }, BinOpKind::Ne => { - check_cmp(cx, expr.span, left, right, "!", 0); // len != 0 - check_cmp(cx, expr.span, right, left, "!", 0); // 0 != len + check_cmp(cx, actual_span, left, right, "!", 0); // len != 0 + check_cmp(cx, actual_span, right, left, "!", 0); // 0 != len }, BinOpKind::Gt => { - check_cmp(cx, expr.span, left, right, "!", 0); // len > 0 - check_cmp(cx, expr.span, right, left, "", 1); // 1 > len + check_cmp(cx, actual_span, left, right, "!", 0); // len > 0 + check_cmp(cx, actual_span, right, left, "", 1); // 1 > len }, BinOpKind::Lt => { - check_cmp(cx, expr.span, left, right, "", 1); // len < 1 - check_cmp(cx, expr.span, right, left, "!", 0); // 0 < len + check_cmp(cx, actual_span, left, right, "", 1); // len < 1 + check_cmp(cx, actual_span, right, left, "!", 0); // 0 < len }, - BinOpKind::Ge => check_cmp(cx, expr.span, left, right, "!", 1), // len >= 1 - BinOpKind::Le => check_cmp(cx, expr.span, right, left, "!", 1), // 1 <= len + BinOpKind::Ge => check_cmp(cx, actual_span, left, right, "!", 1), // len >= 1 + BinOpKind::Le => check_cmp(cx, actual_span, right, left, "!", 1), // 1 <= len _ => (), } } diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs index db41bc67da1a..2f6f36c39604 100644 --- a/clippy_lints/src/let_if_seq.rs +++ b/clippy_lints/src/let_if_seq.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::path_to_local_id; use clippy_utils::source::snippet; -use clippy_utils::{path_to_local_id, visitors::is_local_used}; +use clippy_utils::visitors::is_local_used; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; diff --git a/clippy_lints/src/let_underscore.rs b/clippy_lints/src/let_underscore.rs index 51b5de27de89..93df9e6b8a52 100644 --- a/clippy_lints/src/let_underscore.rs +++ b/clippy_lints/src/let_underscore.rs @@ -1,11 +1,18 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type}; -use clippy_utils::{is_must_use_func_call, paths}; +<<<<<<< HEAD +use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths}; use rustc_hir::{Local, PatKind}; +======= +use clippy_utils::{is_must_use_func_call, paths}; +use rustc_hir::{ExprKind, Local, PatKind}; +>>>>>>> e4f5d83fa (Fixed formatting.) use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::IsSuggestable; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does @@ -137,7 +144,7 @@ const SYNC_GUARD_PATHS: [&[&str]; 3] = [ ]; impl<'tcx> LateLintPass<'tcx> for LetUnderscore { - fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) { + fn check_local(&mut self, cx: &LateContext<'tcx>, local: &Local<'tcx>) { if !in_external_macro(cx.tcx.sess, local.span) && let PatKind::Wild = local.pat.kind && let Some(init) = local.init @@ -189,13 +196,73 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { if local.pat.default_binding_modes && local.ty.is_none() { // When `default_binding_modes` is true, the `let` keyword is present. - span_lint_and_help( + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> cfa5aa2aa (Don't suggest unnameable types in box_default, let_underscore_untyped) + // Ignore unnameable types + if let Some(init) = local.init + && !cx.typeck_results().expr_ty(init).is_suggestable(cx.tcx, true) + { + return; + } +<<<<<<< HEAD +======= +======= +>>>>>>> e4f5d83fa (Fixed formatting.) + // Ignore function calls that return impl traits... + if let Some(init) = local.init && + matches!(init.kind, ExprKind::Call(_, _) | ExprKind::MethodCall(_, _, _, _)) { + let expr_ty = cx.typeck_results().expr_ty(init); + if expr_ty.is_impl_trait() { + return; + } + } +<<<<<<< HEAD +>>>>>>> 2d9d81fc1 (Checking for proc_macro not only when local.init is Some) +======= +>>>>>>> cfa5aa2aa (Don't suggest unnameable types in box_default, let_underscore_untyped) + + // Ignore if it is from a procedural macro... + if is_from_proc_macro(cx, init) { + return; +<<<<<<< HEAD +======= + if let Some(init) = local.init { + // Ignore function calls that return impl traits... + if matches!(init.kind, ExprKind::Call(_, _) | ExprKind::MethodCall(_, _, _, _)) { + let expr_ty = cx.typeck_results().expr_ty(init); + if expr_ty.is_impl_trait() { + return; + } + } + // Ignore if it is from a procedural macro... + if is_from_proc_macro(cx, init) { + return; + } +>>>>>>> e234dfa63 (Ignoring `let_underscore_untyped` warnings in code from proc macros) +======= +>>>>>>> 2d9d81fc1 (Checking for proc_macro not only when local.init is Some) + } +======= + +>>>>>>> e4f5d83fa (Fixed formatting.) + + span_lint_and_help( cx, LET_UNDERSCORE_UNTYPED, local.span, "non-binding `let` without a type annotation", - None, - "consider adding a type annotation or removing the `let` keyword", + Some( + Span::new(local.pat.span.hi(), + local.pat.span.hi() + BytePos(1), + local.pat.span.ctxt(), + local.pat.span.parent() + )), + "consider adding a type annotation", ); } } diff --git a/clippy_lints/src/let_with_type_underscore.rs b/clippy_lints/src/let_with_type_underscore.rs index c01e3882d529..99bf496ecafc 100644 --- a/clippy_lints/src/let_with_type_underscore.rs +++ b/clippy_lints/src/let_with_type_underscore.rs @@ -1,4 +1,14 @@ +<<<<<<< HEAD +<<<<<<< HEAD use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::source::snippet; +======= +use clippy_utils::{diagnostics::span_lint_and_help, is_from_proc_macro}; +>>>>>>> 0cc1454db (Fix #10498) +======= +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::source::snippet; +>>>>>>> 143ff2dfc (Use type snippet instead of init expr for proc macro check) use rustc_hir::{Local, TyKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; @@ -17,7 +27,7 @@ declare_clippy_lint! { /// ```rust,ignore /// let my_number = 1; /// ``` - #[clippy::version = "1.69.0"] + #[clippy::version = "1.70.0"] pub LET_WITH_TYPE_UNDERSCORE, complexity, "unneeded underscore type (`_`) in a variable declaration" @@ -25,14 +35,40 @@ declare_clippy_lint! { declare_lint_pass!(UnderscoreTyped => [LET_WITH_TYPE_UNDERSCORE]); impl LateLintPass<'_> for UnderscoreTyped { - fn check_local<'tcx>(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { + fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) { if_chain! { if !in_external_macro(cx.tcx.sess, local.span); if let Some(ty) = local.ty; // Ensure that it has a type defined if let TyKind::Infer = &ty.kind; // that type is '_' if local.span.ctxt() == ty.span.ctxt(); then { - span_lint_and_help(cx, +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + // NOTE: Using `is_from_proc_macro` on `init` will require that it's initialized, + // this doesn't. Alternatively, `WithSearchPat` can be implemented for `Ty` + if snippet(cx, ty.span, "_").trim() != "_" { +======= + if let Some(init) = local.init && is_from_proc_macro(cx, init) { +>>>>>>> 0cc1454db (Fix #10498) +======= + let underscore_span = ty.span.with_lo(local.pat.span.hi()); + let snippet = snippet(cx, underscore_span, ": _"); + + // NOTE: Using `is_from_proc_macro` on `init` will require that it's initialized, + // this doesn't. Alternatively, `WithSearchPat` can be implemented for `Ty` + if !snippet.trim().starts_with(':') && !snippet.trim().ends_with('_') { +>>>>>>> 143ff2dfc (Use type snippet instead of init expr for proc macro check) +======= + // NOTE: Using `is_from_proc_macro` on `init` will require that it's initialized, + // this doesn't. Alternatively, `WithSearchPat` can be implemented for `Ty` + if snippet(cx, ty.span, "_").trim() != "_" { +>>>>>>> ba1fb74bf (check for `_` instead) + return; + } + + span_lint_and_help( + cx, LET_WITH_TYPE_UNDERSCORE, local.span, "variable declared with type underscore", diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index b0ec14855e71..61d465e2b59e 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -68,6 +68,7 @@ mod renamed_lints; mod allow_attributes; mod almost_complete_range; mod approx_const; +mod arc_with_non_send_sync; mod as_conversions; mod asm_syntax; mod assertions_on_constants; @@ -94,6 +95,15 @@ mod crate_in_macro_def; mod create_dir; mod dbg_macro; mod default; +<<<<<<< HEAD +<<<<<<< HEAD +mod default_constructed_unit_structs; +======= +mod default_constructed_unit_struct; +>>>>>>> 942813856 (adds lint to detect construction of unit struct using `default`) +======= +mod default_constructed_unit_structs; +>>>>>>> 4e0490363 (rename to plural form) mod default_instead_of_iter_empty; mod default_numeric_fallback; mod default_union_representation; @@ -113,6 +123,7 @@ mod else_if_without_else; mod empty_drop; mod empty_enum; mod empty_structs_with_brackets; +mod endian_bytes; mod entry; mod enum_clike; mod enum_variants; @@ -120,6 +131,15 @@ mod equatable_if_let; mod escape; mod eta_reduction; mod excessive_bools; +<<<<<<< HEAD +<<<<<<< HEAD +mod excessive_nesting; +======= +mod excessive_width; +>>>>>>> 97c10075e (add the `excessive_*` style lints) +======= +mod excessive_nesting; +>>>>>>> e68dbc330 (add `excessive_nesting`) mod exhaustive_items; mod exit; mod explicit_write; @@ -127,7 +147,6 @@ mod extra_unused_type_parameters; mod fallible_impl_from; mod float_literal; mod floating_point_arithmetic; -mod fn_null_check; mod format; mod format_args; mod format_impl; @@ -146,6 +165,7 @@ mod implicit_return; mod implicit_saturating_add; mod implicit_saturating_sub; mod inconsistent_struct_constructor; +mod incorrect_impls; mod index_refutable_slice; mod indexing_slicing; mod infinite_iter; @@ -156,14 +176,15 @@ mod inline_fn_without_body; mod instant_subtraction; mod int_plus_one; mod invalid_upcast_comparisons; -mod invalid_utf8_in_unchecked; mod items_after_statements; +mod items_after_test_module; mod iter_not_returning_iterator; mod large_const_arrays; mod large_enum_variant; mod large_futures; mod large_include_file; mod large_stack_arrays; +mod large_stack_frames; mod len_zero; mod let_if_seq; mod let_underscore; @@ -178,10 +199,27 @@ mod manual_assert; mod manual_async_fn; mod manual_bits; mod manual_clamp; +mod manual_float_methods; mod manual_is_ascii_check; mod manual_let_else; mod manual_main_separator_str; mod manual_non_exhaustive; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +mod manual_partial_ord_impl; +>>>>>>> 2a1fd22f8 (implement `manual_partial_ord_impl`) +======= +>>>>>>> 004e89d4c (rename to `manual_partial_ord_and_ord_impl`) +mod manual_range_patterns; +======= +mod manual_range_pattern; +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) +======= +mod manual_range_patterns; +>>>>>>> b592d3996 (manual_range_pattern -> manual_range_patterns) mod manual_rem_euclid; mod manual_retain; mod manual_slice_size_calculation; @@ -190,9 +228,9 @@ mod manual_strip; mod map_unit_fn; mod match_result_ok; mod matches; -mod mem_forget; mod mem_replace; mod methods; +mod min_ident_chars; mod minmax; mod misc; mod misc_early; @@ -201,6 +239,7 @@ mod missing_assert_message; mod missing_const_for_fn; mod missing_doc; mod missing_enforced_import_rename; +mod missing_fields_in_debug; mod missing_inline; mod missing_trait_methods; mod mixed_read_write_in_expression; @@ -216,9 +255,12 @@ mod needless_arbitrary_self_type; mod needless_bool; mod needless_borrowed_ref; mod needless_continue; +mod needless_else; mod needless_for_each; +mod needless_if; mod needless_late_init; mod needless_parens_on_range_literals; +mod needless_pass_by_ref_mut; mod needless_pass_by_value; mod needless_question_mark; mod needless_update; @@ -253,6 +295,7 @@ mod pub_use; mod question_mark; mod question_mark_used; mod ranges; +mod raw_strings; mod rc_clone_in_vec_init; mod read_zero_byte_vec; mod redundant_async_block; @@ -263,7 +306,9 @@ mod redundant_field_names; mod redundant_pub_crate; mod redundant_slicing; mod redundant_static_lifetimes; +mod redundant_type_annotations; mod ref_option_ref; +mod ref_patterns; mod reference; mod regex; mod return_self_not_must_use; @@ -275,8 +320,30 @@ mod semicolon_if_nothing_returned; mod serde_api; mod shadow; mod significant_drop_tightening; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) +mod single_call_fn; mod single_char_lifetime_names; mod single_component_path_imports; +<<<<<<< HEAD +<<<<<<< HEAD +mod single_range_in_vec_init; +======= +mod single_letter_idents; +>>>>>>> 52cfc997a (Add lint `single_letter_idents`) +======= +mod single_char_idents; +======= +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +mod single_char_lifetime_names; +mod single_component_path_imports; +>>>>>>> e2ecb132a (rename the lint) +======= +mod single_range_in_vec_init; +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) mod size_of_in_element_count; mod size_of_ref; mod slow_vector_initialization; @@ -296,6 +363,7 @@ mod to_digit_is_some; mod trailing_empty_array; mod trait_bounds; mod transmute; +mod tuple_array_conversions; mod types; mod undocumented_unsafe_blocks; mod unicode; @@ -323,14 +391,25 @@ mod use_self; mod useless_conversion; mod vec; mod vec_init_then_push; +mod visibility; mod wildcard_imports; mod write; mod zero_div_zero; mod zero_sized_map_values; // end lints modules, do not remove this comment, it’s used in `update_lints` -use crate::utils::conf::{format_error, TryConf}; +<<<<<<< HEAD +use crate::utils::conf::metadata::get_configuration_metadata; +use crate::utils::conf::TryConf; pub use crate::utils::conf::{lookup_conf_file, Conf}; +use crate::utils::FindAll; +======= +pub use crate::utils::conf::{lookup_conf_file, Conf}; +use crate::utils::{ + conf::{format_error, metadata::get_configuration_metadata, TryConf}, + FindAll, +}; +>>>>>>> e4f5d83fa (Fixed formatting.) /// Register all pre expansion lints /// @@ -352,7 +431,15 @@ pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore, sess: &Se pub fn read_conf(sess: &Session, path: &io::Result<(Option, Vec)>) -> Conf { if let Ok((_, warnings)) = path { for warning in warnings { +<<<<<<< HEAD +<<<<<<< HEAD + sess.warn(warning.clone()); +======= sess.warn(warning); +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + sess.warn(warning.clone()); +>>>>>>> 431cce154 (Restrict `From` for `{D,Subd}iagnosticMessage`.) } } let file_name = match path { @@ -364,29 +451,42 @@ pub fn read_conf(sess: &Session, path: &io::Result<(Option, Vec }, }; - let TryConf { conf, errors, warnings } = utils::conf::read(file_name); + let TryConf { conf, errors, warnings } = utils::conf::read(sess, file_name); // all conf errors are non-fatal, we just use the default conf in case of error for error in errors { - sess.err(format!( - "error reading Clippy's configuration file `{}`: {}", - file_name.display(), - format_error(error) - )); + if let Some(span) = error.span { + sess.span_err( + span, + format!("error reading Clippy's configuration file: {}", error.message), + ); + } else { + sess.err(format!( + "error reading Clippy's configuration file `{}`: {}", + file_name.display(), + error.message + )); + } } for warning in warnings { - sess.struct_warn(format!( - "error reading Clippy's configuration file `{}`: {}", - file_name.display(), - format_error(warning) - )) - .emit(); + if let Some(span) = warning.span { + sess.span_warn( + span, + format!("error reading Clippy's configuration file: {}", warning.message), + ); + } else { + sess.warn(format!( + "error reading Clippy's configuration file `{}`: {}", + file_name.display(), + warning.message + )); + } } conf } -#[derive(Default)] +#[derive(Default)] //~ ERROR no such field struct RegistrationGroups { all: Vec, cargo: Vec, @@ -466,11 +566,93 @@ pub(crate) struct LintInfo { explanation: &'static str, } -pub fn explain(name: &str) { +pub fn explain(name: &str) -> i32 { let target = format!("clippy::{}", name.to_ascii_uppercase()); +<<<<<<< HEAD +<<<<<<< HEAD match declared_lints::LINTS.iter().find(|info| info.lint.name == target) { - Some(info) => print!("{}", info.explanation), + Some(info) => { + println!("{}", info.explanation); + // Check if the lint has configuration + let mdconf = get_configuration_metadata(); + if let Some(config_vec_positions) = mdconf + .iter() + .find_all(|cconf| cconf.lints.contains(&info.lint.name_lower()[8..].to_owned())) + { + // If it has, print it +<<<<<<< HEAD +<<<<<<< HEAD + println!("### Configuration for {}:\n", info.lint.name_lower()); + for position in config_vec_positions { + let conf = &mdconf[position]; + println!(" - {}: {} (default: {})", conf.name, conf.doc, conf.default); +======= + println!("### Configuration for {}:", info.lint.name_lower()); + for position in config_vec_positions { + let conf = &mdconf[position]; + println!(" - {}: {} (default: {})", conf.name, conf.doc, conf.default); +>>>>>>> 2a4571d95 (Minimizing changes) +======= + println!("### Configuration for {}:\n", info.lint.name_lower()); + for position in config_vec_positions { + let conf = &mdconf[position]; + println!(" - {}: {} (default: {})", conf.name, conf.doc, conf.default); +>>>>>>> 3e8fea612 (Fix config formatting, less indenting, more spacing) + } +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) + if let Some(info) = declared_lints::LINTS.iter().find(|info| info.lint.name == target) { + println!("{}", info.explanation); + // Check if the lint has configuration + let mdconf = get_configuration_metadata(); + if let Some(config_vec_positions) = mdconf + .iter() + .find_all(|cconf| cconf.lints.contains(&info.lint.name_lower()[8..].to_owned())) + { + // If it has, print it + println!("### Configuration for {}:\n", info.lint.name_lower()); + for position in config_vec_positions { + let conf = &mdconf[position]; + println!(" - {}: {} (default: {})", conf.name, conf.doc, conf.default); +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) + } + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 894d5dafa (Make `--explain` subcommand return 1 for missing lints) + 0 + } else { + println!("unknown lint: {name}"); + 1 +<<<<<<< HEAD +======= + } else { + println!("unknown lint: {name}"); +>>>>>>> a94aac607 (Refactor to make following commit pass single_match_else lint) +======= +>>>>>>> 894d5dafa (Make `--explain` subcommand return 1 for missing lints) +======= + match declared_lints::LINTS.iter().find(|info| info.lint.name == target) { + Some(info) => { + println!("{}", info.explanation); + // Check if the lint has configuration + let mdconf = get_configuration_metadata(); + if let Some(config_vec_positions) = mdconf + .iter() + .find_all(|cconf| cconf.lints.contains(&info.lint.name_lower()[8..].to_owned())) + { + // If it has, print it + println!("### Configuration for {}:\n", info.lint.name_lower()); + for position in config_vec_positions { + let conf = &mdconf[position]; + println!(" - {}: {} (default: {})", conf.name, conf.doc, conf.default); + } + } + }, None => println!("unknown lint: {name}"), +>>>>>>> e4f5d83fa (Fixed formatting.) } } @@ -529,6 +711,9 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::::default()); store.register_late_pass(|_| Box::new(utils::internal_lints::outer_expn_data_pass::OuterExpnDataPass)); store.register_late_pass(|_| Box::new(utils::internal_lints::msrv_attr_impl::MsrvAttrImpl)); + store.register_late_pass(|_| { + Box::new(utils::internal_lints::almost_standard_lint_formulation::AlmostStandardFormulation::new()) + }); } let arithmetic_side_effects_allowed = conf.arithmetic_side_effects_allowed.clone(); @@ -611,7 +796,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: }); store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv()))); let matches_for_let_else = conf.matches_for_let_else; - store.register_late_pass(move |_| Box::new(manual_let_else::ManualLetElse::new(msrv(), matches_for_let_else))); store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv()))); store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv()))); store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(msrv()))); @@ -637,7 +821,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: }); store.register_late_pass(|_| Box::::default()); store.register_late_pass(|_| Box::new(unit_types::UnitTypes)); - store.register_late_pass(|_| Box::new(loops::Loops)); + store.register_late_pass(move |_| Box::new(loops::Loops::new(msrv()))); store.register_late_pass(|_| Box::::default()); store.register_late_pass(|_| Box::new(lifetimes::Lifetimes)); store.register_late_pass(|_| Box::new(entry::HashMapPass)); @@ -658,7 +842,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: }); let too_large_for_stack = conf.too_large_for_stack; store.register_late_pass(move |_| Box::new(escape::BoxedLocal { too_large_for_stack })); - store.register_late_pass(move |_| Box::new(vec::UselessVec { too_large_for_stack })); + store.register_late_pass(move |_| { + Box::new(vec::UselessVec { + too_large_for_stack, + msrv: msrv(), + }) + }); store.register_late_pass(|_| Box::new(panic_unimplemented::PanicUnimplemented)); store.register_late_pass(|_| Box::new(strings::StringLitAsBytes)); store.register_late_pass(|_| Box::new(derive::Derive)); @@ -666,7 +855,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(drop_forget_ref::DropForgetRef)); store.register_late_pass(|_| Box::new(empty_enum::EmptyEnum)); store.register_late_pass(|_| Box::new(invalid_upcast_comparisons::InvalidUpcastComparisons)); - store.register_late_pass(|_| Box::new(regex::Regex)); + store.register_late_pass(|_| Box::::default()); let ignore_interior_mutability = conf.ignore_interior_mutability.clone(); store.register_late_pass(move |_| Box::new(copies::CopyAndPaste::new(ignore_interior_mutability.clone()))); store.register_late_pass(|_| Box::new(copy_iterator::CopyIterator)); @@ -690,7 +879,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: let missing_docs_in_crate_items = conf.missing_docs_in_crate_items; store.register_late_pass(move |_| Box::new(doc::DocMarkdown::new(doc_valid_idents.clone()))); store.register_late_pass(|_| Box::new(neg_multiply::NegMultiply)); - store.register_late_pass(|_| Box::new(mem_forget::MemForget)); store.register_late_pass(|_| Box::new(let_if_seq::LetIfSeq)); store.register_late_pass(|_| Box::new(mixed_read_write_in_expression::EvalOrderDependence)); store.register_late_pass(move |_| Box::new(missing_doc::MissingDoc::new(missing_docs_in_crate_items))); @@ -716,7 +904,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::::default()); store.register_late_pass(|_| Box::new(implicit_hasher::ImplicitHasher)); store.register_late_pass(|_| Box::new(fallible_impl_from::FallibleImplFrom)); - store.register_late_pass(|_| Box::new(question_mark::QuestionMark)); + store.register_late_pass(move |_| Box::new(question_mark::QuestionMark::new(msrv(), matches_for_let_else))); store.register_late_pass(|_| Box::new(question_mark_used::QuestionMarkUsed)); store.register_early_pass(|| Box::new(suspicious_operation_groupings::SuspiciousOperationGroupings)); store.register_late_pass(|_| Box::new(suspicious_trait_impl::SuspiciousImpl)); @@ -738,7 +926,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(assertions_on_result_states::AssertionsOnResultStates)); store.register_late_pass(|_| Box::new(inherent_to_string::InherentToString)); let max_trait_bounds = conf.max_trait_bounds; - store.register_late_pass(move |_| Box::new(trait_bounds::TraitBounds::new(max_trait_bounds))); + store.register_late_pass(move |_| Box::new(trait_bounds::TraitBounds::new(max_trait_bounds, msrv()))); store.register_late_pass(|_| Box::new(comparison_chain::ComparisonChain)); let ignore_interior_mutability = conf.ignore_interior_mutability.clone(); store.register_late_pass(move |_| Box::new(mut_key::MutableKeyType::new(ignore_interior_mutability.clone()))); @@ -750,7 +938,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_early_pass(|| Box::new(int_plus_one::IntPlusOne)); store.register_early_pass(|| Box::new(formatting::Formatting)); store.register_early_pass(|| Box::new(misc_early::MiscEarlyLints)); - store.register_early_pass(|| Box::new(redundant_closure_call::RedundantClosureCall)); store.register_late_pass(|_| Box::new(redundant_closure_call::RedundantClosureCall)); store.register_early_pass(|| Box::new(unused_unit::UnusedUnit)); store.register_late_pass(|_| Box::new(returns::Return)); @@ -775,10 +962,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: )) }); let enum_variant_name_threshold = conf.enum_variant_name_threshold; + let allow_private_module_inception = conf.allow_private_module_inception; store.register_late_pass(move |_| { Box::new(enum_variants::EnumVariantNames::new( enum_variant_name_threshold, avoid_breaking_exported_api, + allow_private_module_inception, )) }); store.register_early_pass(|| Box::new(tabs_in_doc_comments::TabsInDocComments)); @@ -798,7 +987,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(move |_| Box::new(large_stack_arrays::LargeStackArrays::new(array_size_threshold))); store.register_late_pass(move |_| Box::new(large_const_arrays::LargeConstArrays::new(array_size_threshold))); store.register_late_pass(|_| Box::new(floating_point_arithmetic::FloatingPointArithmetic)); - store.register_early_pass(|| Box::new(as_conversions::AsConversions)); + store.register_late_pass(|_| Box::new(as_conversions::AsConversions)); store.register_late_pass(|_| Box::new(let_underscore::LetUnderscore)); store.register_early_pass(|| Box::::default()); let max_fn_params_bools = conf.max_fn_params_bools; @@ -874,7 +1063,26 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: enable_raw_pointer_heuristic_for_send, )) }); - store.register_late_pass(move |_| Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks)); + let accept_comment_above_statement = conf.accept_comment_above_statement; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) + let accept_comment_above_attributes = conf.accept_comment_above_attributes; + store.register_late_pass(move |_| { + Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks::new( + accept_comment_above_statement, + accept_comment_above_attributes, +<<<<<<< HEAD +======= + store.register_late_pass(move |_| { + Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks::new( + accept_comment_above_statement, +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) + )) + }); let allow_mixed_uninlined = conf.allow_mixed_uninlined_format_args; store.register_late_pass(move |_| Box::new(format_args::FormatArgs::new(msrv(), allow_mixed_uninlined))); store.register_late_pass(|_| Box::new(trailing_empty_array::TrailingEmptyArray)); @@ -916,7 +1124,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(msrv()))); let verbose_bit_mask_threshold = conf.verbose_bit_mask_threshold; store.register_late_pass(move |_| Box::new(operators::Operators::new(verbose_bit_mask_threshold))); - store.register_late_pass(|_| Box::new(invalid_utf8_in_unchecked::InvalidUtf8InUnchecked)); store.register_late_pass(|_| Box::::default()); store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(msrv()))); store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone)); @@ -932,8 +1139,36 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(from_raw_with_void_ptr::FromRawWithVoidPtr)); store.register_late_pass(|_| Box::new(suspicious_xor_used_as_pow::ConfusingXorAndPow)); store.register_late_pass(move |_| Box::new(manual_is_ascii_check::ManualIsAsciiCheck::new(msrv()))); - store.register_late_pass(|_| Box::new(semicolon_block::SemicolonBlock)); +<<<<<<< HEAD +<<<<<<< HEAD + let semicolon_inside_block_ignore_singleline = conf.semicolon_inside_block_ignore_singleline; + let semicolon_outside_block_ignore_multiline = conf.semicolon_outside_block_ignore_multiline; + store.register_late_pass(move |_| { + Box::new(semicolon_block::SemicolonBlock::new( + semicolon_inside_block_ignore_singleline, + semicolon_outside_block_ignore_multiline, +======= + let semicolon_inside_block_if_multiline = conf.semicolon_inside_block_if_multiline; + let semicolon_outside_block_if_singleline = conf.semicolon_outside_block_if_singleline; + store.register_late_pass(move |_| { + Box::new(semicolon_block::SemicolonBlock::new( + semicolon_inside_block_if_multiline, + semicolon_outside_block_if_singleline, +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= + let semicolon_inside_block_ignore_singleline = conf.semicolon_inside_block_ignore_singleline; + let semicolon_outside_block_ignore_multiline = conf.semicolon_outside_block_ignore_multiline; + store.register_late_pass(move |_| { + Box::new(semicolon_block::SemicolonBlock::new( + semicolon_inside_block_ignore_singleline, + semicolon_outside_block_ignore_multiline, +>>>>>>> aa6c27a74 (change names to not be implicitly negative) + )) + }); +<<<<<<< HEAD +======= store.register_late_pass(|_| Box::new(fn_null_check::FnNullCheck)); +>>>>>>> e4f5d83fa (Fixed formatting.) store.register_late_pass(|_| Box::new(permissions_set_readonly_false::PermissionsSetReadonlyFalse)); store.register_late_pass(|_| Box::new(size_of_ref::SizeOfRef)); store.register_late_pass(|_| Box::new(multiple_unsafe_ops_per_block::MultipleUnsafeOpsPerBlock)); @@ -950,15 +1185,246 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(allow_attributes::AllowAttribute)); store.register_late_pass(move |_| Box::new(manual_main_separator_str::ManualMainSeparatorStr::new(msrv()))); store.register_late_pass(|_| Box::new(unnecessary_struct_initialization::UnnecessaryStruct)); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) + let unnecessary_box_size = conf.unnecessary_box_size; store.register_late_pass(move |_| { Box::new(unnecessary_box_returns::UnnecessaryBoxReturns::new( avoid_breaking_exported_api, + unnecessary_box_size, +<<<<<<< HEAD +<<<<<<< HEAD +======= + store.register_late_pass(move |_| { + Box::new(unnecessary_box_returns::UnnecessaryBoxReturns::new( + avoid_breaking_exported_api, +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) )) }); store.register_late_pass(|_| Box::new(lines_filter_map_ok::LinesFilterMapOk)); store.register_late_pass(|_| Box::new(tests_outside_test_module::TestsOutsideTestModule)); store.register_late_pass(|_| Box::new(manual_slice_size_calculation::ManualSliceSizeCalculation)); store.register_early_pass(|| Box::new(suspicious_doc_comments::SuspiciousDocComments)); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + store.register_late_pass(|_| Box::new(items_after_test_module::ItemsAfterTestModule)); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 56e8e1a27 (new lint: clippy::ref_patterns) +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +======= +>>>>>>> e68dbc330 (add `excessive_nesting`) + let excessive_nesting_threshold = conf.excessive_nesting_threshold; + store.register_early_pass(move || { + Box::new(excessive_nesting::ExcessiveNesting { + excessive_nesting_threshold, +<<<<<<< HEAD +<<<<<<< HEAD + nodes: rustc_ast::node_id::NodeSet::new(), +======= + let excessive_width_threshold = conf.excessive_width_threshold; + let excessive_width_ignore_indentation = conf.excessive_width_ignore_indentation; + let excessive_indentation_threshold = conf.excessive_indentation_threshold; + store.register_late_pass(move |_| { + Box::new(excessive_width::ExcessiveWidth { + excessive_width_threshold, + excessive_width_ignore_indentation, + excessive_indentation_threshold, +>>>>>>> 97c10075e (add the `excessive_*` style lints) +======= +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + nodes: rustc_ast::node_id::NodeSet::new(), +>>>>>>> 378d77584 (work with lint attributes) + }) + }); + store.register_late_pass(|_| Box::new(items_after_test_module::ItemsAfterTestModule)); +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) + store.register_early_pass(|| Box::new(ref_patterns::RefPatterns)); +======= +>>>>>>> 7e9abb311 (Merge commit '371120bdbf58a331db5dcfb2d9cddc040f486de8' into clippyup) +======= + store.register_early_pass(|| Box::new(ref_patterns::RefPatterns)); +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) + store.register_late_pass(|_| Box::new(default_constructed_unit_structs::DefaultConstructedUnitStructs)); +<<<<<<< HEAD +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + store.register_late_pass(|_| Box::new(items_after_test_module::ItemsAfterTestModule)); +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + store.register_late_pass(|_| Box::new(items_after_test_module::ItemsAfterTestModule)); +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= + store.register_late_pass(|_| Box::new(default_constructed_unit_struct::DefaultConstructedUnitStruct)); +>>>>>>> 942813856 (adds lint to detect construction of unit struct using `default`) +======= + store.register_late_pass(|_| Box::new(default_constructed_unit_structs::DefaultConstructedUnitStructs)); +>>>>>>> 4e0490363 (rename to plural form) +======= + store.register_early_pass(|| Box::new(needless_else::NeedlessElse)); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + store.register_late_pass(|_| Box::new(missing_fields_in_debug::MissingFieldsInDebug)); + store.register_late_pass(|_| Box::new(endian_bytes::EndianBytes)); +<<<<<<< HEAD +<<<<<<< HEAD + store.register_late_pass(|_| Box::new(redundant_type_annotations::RedundantTypeAnnotations)); + store.register_late_pass(|_| Box::new(arc_with_non_send_sync::ArcWithNonSendSync)); +<<<<<<< HEAD +<<<<<<< HEAD + store.register_late_pass(|_| Box::new(needless_if::NeedlessIf)); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) + let allowed_idents_below_min_chars = conf.allowed_idents_below_min_chars.clone(); + let min_ident_chars_threshold = conf.min_ident_chars_threshold; + store.register_late_pass(move |_| { + Box::new(min_ident_chars::MinIdentChars { + allowed_idents_below_min_chars: allowed_idents_below_min_chars.clone(), + min_ident_chars_threshold, +<<<<<<< HEAD + }) + }); + let stack_size_threshold = conf.stack_size_threshold; + store.register_late_pass(move |_| Box::new(large_stack_frames::LargeStackFrames::new(stack_size_threshold))); +<<<<<<< HEAD +<<<<<<< HEAD + store.register_late_pass(|_| Box::new(single_range_in_vec_init::SingleRangeInVecInit)); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= + store.register_late_pass(|_| Box::new(needless_pass_by_ref_mut::NeedlessPassByRefMut)); +>>>>>>> b41fc6784 (Add needless_pass_by_ref lint) +======= + store.register_late_pass(move |_| { + Box::new(needless_pass_by_ref_mut::NeedlessPassByRefMut::new( + avoid_breaking_exported_api, + )) + }); +>>>>>>> f048f7325 (Add warning about semver compatibility if it's a public function) + store.register_late_pass(|_| Box::new(incorrect_impls::IncorrectImpls)); + store.register_late_pass(move |_| { + Box::new(single_call_fn::SingleCallFn { + avoid_breaking_exported_api, + def_id_to_usage: rustc_data_structures::fx::FxHashMap::default(), + }) + }); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 8cb6c8699 (change category and refactor) + let needless_raw_string_hashes_allow_one = conf.allow_one_hash_in_raw_strings; + store.register_early_pass(move || { + Box::new(raw_strings::RawStrings { + needless_raw_string_hashes_allow_one, + }) + }); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + store.register_late_pass(|_| Box::new(manual_range_patterns::ManualRangePatterns)); + store.register_early_pass(|| Box::new(visibility::Visibility)); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + store.register_late_pass(move |_| Box::new(tuple_array_conversions::TupleArrayConversions { msrv: msrv() })); +<<<<<<< HEAD +======= +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= + store.register_late_pass(|_| Box::new(missing_fields_in_debug::MissingFieldsInDebug)); +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= + store.register_late_pass(|_| Box::new(explicit_into_iter_fn_arg::ExplicitIntoIterFnArg)); +>>>>>>> 516f4f6ae (new lint: `explicit_into_iter_fn_arg`) +======= +>>>>>>> de1f41001 (merge `explicit_into_iter_fn_arg` into `useless_conversion`) +======= +>>>>>>> 3ab6aeefb (`to_xx_bytes` implemented, `from_xx_bytes` todo) +======= + store.register_late_pass(|_| Box::new(redundant_type_annotations::RedundantTypeAnnotations)); +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= +>>>>>>> 339cd14f2 (Adds new lint `arc_with_non_send_or_sync`) +======= + store.register_late_pass(|_| Box::new(needless_if::NeedlessIf)); +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + let allowed_idents = conf.allowed_idents.clone(); + store.register_early_pass(move || { + Box::new(single_char_idents::SingleCharIdents { + allowed_idents: allowed_idents.clone(), +======= +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) + }) + }); +>>>>>>> 52cfc997a (Add lint `single_letter_idents`) +======= +>>>>>>> 7312a93a0 (new lint: `large_stack_frames`) +======= + store.register_late_pass(|_| Box::new(single_range_in_vec_init::SingleRangeInVecInit)); +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= + store.register_late_pass(|_| Box::new(needless_impls::NeedlessImpls)); +>>>>>>> 67d5e6ec3 (add lint [`needless_clone_impl`]) +======= + store.register_late_pass(|_| Box::new(incorrect_impls::IncorrectImpls)); +>>>>>>> 10cc1684c (rename lint and disallow `clone_from`) +======= +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) +======= +>>>>>>> 8cb6c8699 (change category and refactor) +======= + store.register_late_pass(|_| Box::new(manual_range_pattern::ManualRangePattern)); +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) +======= + store.register_late_pass(|_| Box::new(manual_range_patterns::ManualRangePatterns)); +>>>>>>> b592d3996 (manual_range_pattern -> manual_range_patterns) +======= +>>>>>>> 8296a338d (new lints for visibility) +======= + store.register_late_pass(|_| Box::new(tuple_array_conversions::TupleArrayConversions)); +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + store.register_late_pass(move |_| Box::new(tuple_array_conversions::TupleArrayConversions { msrv: msrv() })); +>>>>>>> b1acbde61 (Add msrv check and make test pass) +======= + store.register_late_pass(|_| Box::new(manual_float_methods::ManualFloatMethods)); +>>>>>>> f12edfdb5 (`manual_float_methods`) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= + store.register_late_pass(|_| Box::new(items_after_test_module::ItemsAfterTestModule)); + store.register_early_pass(|| Box::new(ref_patterns::RefPatterns)); + store.register_late_pass(|_| Box::new(default_constructed_unit_structs::DefaultConstructedUnitStructs)); +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 986ffcad883d..852f6736585b 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; use clippy_utils::trait_ref_of_method; +use itertools::Itertools; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::Applicability; use rustc_hir::intravisit::nested_filter::{self as hir_nested_filter, NestedFilter}; @@ -201,7 +202,19 @@ fn check_fn_inner<'tcx>( span_lint_and_then( cx, NEEDLESS_LIFETIMES, - span.with_hi(sig.decl.output.span().hi()), + elidable_lts + .iter() + .map(|<| cx.tcx.def_span(lt)) + .chain(usages.iter().filter_map(|usage| { + if let LifetimeName::Param(def_id) = usage.res + && elidable_lts.contains(&def_id) + { + return Some(usage.ident.span); + } + + None + })) + .collect_vec(), &format!("the following explicit lifetimes could be elided: {lts}"), |diag| { if sig.header.is_async() { @@ -562,7 +575,7 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_ // if the bounds define new lifetimes, they are fine to occur let allowed_lts = allowed_lts_from(pred.bound_generic_params); // now walk the bounds - for bound in pred.bounds.iter() { + for bound in pred.bounds { walk_param_bound(&mut visitor, bound); } // and check that all lifetimes are allowed diff --git a/clippy_lints/src/lines_filter_map_ok.rs b/clippy_lints/src/lines_filter_map_ok.rs index bba9bb445a77..c1c202808812 100644 --- a/clippy_lints/src/lines_filter_map_ok.rs +++ b/clippy_lints/src/lines_filter_map_ok.rs @@ -1,7 +1,6 @@ -use clippy_utils::{ - diagnostics::span_lint_and_then, is_diag_item_method, is_trait_method, match_def_path, path_to_local_id, paths, - ty::match_type, -}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::ty::match_type; +use clippy_utils::{is_diag_item_method, is_trait_method, match_def_path, path_to_local_id, paths}; use rustc_errors::Applicability; use rustc_hir::{Body, Closure, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -10,7 +9,29 @@ use rustc_span::sym; declare_clippy_lint! { /// ### What it does +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) /// Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)` +======= + /// Detect uses of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)` +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + /// Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)` +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +<<<<<<< HEAD +======= + /// Detect uses of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)` +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + /// Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)` +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) /// when `lines` has type `std::io::Lines`. /// /// ### Why is this bad? @@ -25,7 +46,15 @@ declare_clippy_lint! { /// /// ### Known problems /// This lint suggests replacing `filter_map()` or `flat_map()` applied to a `Lines` +<<<<<<< HEAD +<<<<<<< HEAD + /// instance in all cases. There are two cases where the suggestion might not be +======= /// instance in all cases. There two cases where the suggestion might not be +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + /// instance in all cases. There are two cases where the suggestion might not be +>>>>>>> f4b8cb1b2 (Add missing word "are") /// appropriate or necessary: /// /// - If the `Lines` instance can never produce any error, or if an error is produced diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index dadcd9c5135c..09ca0317337c 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -264,7 +264,7 @@ impl LiteralDigitGrouping { return; } - if Self::is_literal_uuid_formatted(&mut num_lit) { + if Self::is_literal_uuid_formatted(&num_lit) { return; } @@ -376,7 +376,7 @@ impl LiteralDigitGrouping { /// /// Returns `true` if the radix is hexadecimal, and the groups match the /// UUID format of 8-4-4-4-12. - fn is_literal_uuid_formatted(num_lit: &mut NumericLiteral<'_>) -> bool { + fn is_literal_uuid_formatted(num_lit: &NumericLiteral<'_>) -> bool { if num_lit.radix != Radix::Hexadecimal { return false; } diff --git a/clippy_lints/src/loops/explicit_into_iter_loop.rs b/clippy_lints/src/loops/explicit_into_iter_loop.rs index 175e2b382e3f..c365134cfefe 100644 --- a/clippy_lints/src/loops/explicit_into_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_into_iter_loop.rs @@ -5,15 +5,76 @@ use clippy_utils::source::snippet_with_applicability; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; +use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_span::symbol::sym; +#[derive(Clone, Copy)] +enum AdjustKind { + None, + Borrow, + BorrowMut, + Reborrow, + ReborrowMut, +} +impl AdjustKind { + fn borrow(mutbl: AutoBorrowMutability) -> Self { + match mutbl { + AutoBorrowMutability::Not => Self::Borrow, + AutoBorrowMutability::Mut { .. } => Self::BorrowMut, + } + } + + fn reborrow(mutbl: AutoBorrowMutability) -> Self { + match mutbl { + AutoBorrowMutability::Not => Self::Reborrow, + AutoBorrowMutability::Mut { .. } => Self::ReborrowMut, + } + } + + fn display(self) -> &'static str { + match self { + Self::None => "", + Self::Borrow => "&", + Self::BorrowMut => "&mut ", + Self::Reborrow => "&*", + Self::ReborrowMut => "&mut *", + } + } +} + pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<'_>) { - let self_ty = cx.typeck_results().expr_ty(self_arg); - let self_ty_adjusted = cx.typeck_results().expr_ty_adjusted(self_arg); - if !(self_ty == self_ty_adjusted && is_trait_method(cx, call_expr, sym::IntoIterator)) { + if !is_trait_method(cx, call_expr, sym::IntoIterator) { return; } + let typeck = cx.typeck_results(); + let self_ty = typeck.expr_ty(self_arg); + let adjust = match typeck.expr_adjustments(self_arg) { + [] => AdjustKind::None, + &[ + Adjustment { + kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), + .. + }, + ] => AdjustKind::borrow(mutbl), + &[ + Adjustment { + kind: Adjust::Deref(_), .. + }, + Adjustment { + kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), + target, + }, + ] => { + if self_ty == target && matches!(mutbl, AutoBorrowMutability::Not) { + AdjustKind::None + } else { + AdjustKind::reborrow(mutbl) + } + }, + _ => return, + }; + let mut applicability = Applicability::MachineApplicable; let object = snippet_with_applicability(cx, self_arg.span, "_", &mut applicability); span_lint_and_sugg( @@ -23,7 +84,15 @@ pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr< "it is more concise to loop over containers instead of using explicit \ iteration methods", "to write this more concisely, try", - object.to_string(), +<<<<<<< HEAD +<<<<<<< HEAD + format!("{}{object}", adjust.display()), +======= + format!("{}{}", adjust.display(), object.to_string()), +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) +======= + format!("{}{object}", adjust.display()), +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) applicability, ); } diff --git a/clippy_lints/src/loops/explicit_iter_loop.rs b/clippy_lints/src/loops/explicit_iter_loop.rs index 151c7f1d5d25..ccca665e9ad8 100644 --- a/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_iter_loop.rs @@ -1,75 +1,431 @@ use super::EXPLICIT_ITER_LOOP; use clippy_utils::diagnostics::span_lint_and_sugg; +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::source::snippet_with_applicability; +use clippy_utils::ty::{ + implements_trait, implements_trait_with_env, is_copy, make_normalized_projection, + make_normalized_projection_with_regions, normalize_with_regions, +}; +======= use clippy_utils::is_trait_method; +use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::source::snippet_with_applicability; +use clippy_utils::ty::{implements_trait_with_env, make_normalized_projection_with_regions, normalize_with_regions, + make_normalized_projection, implements_trait, is_copy}; +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::ty::{ + implements_trait, implements_trait_with_env, is_copy, make_normalized_projection, + make_normalized_projection_with_regions, normalize_with_regions, +}; +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) use rustc_errors::Applicability; use rustc_hir::{Expr, Mutability}; use rustc_lint::LateContext; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; +<<<<<<< HEAD +<<<<<<< HEAD +use rustc_middle::ty::{self, EarlyBinder, Ty, TypeAndMut}; use rustc_span::sym; -pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, arg: &Expr<'_>, method_name: &str) { - let should_lint = match method_name { - "iter" | "iter_mut" => is_ref_iterable_type(cx, self_arg), - "into_iter" if is_trait_method(cx, arg, sym::IntoIterator) => { - let receiver_ty = cx.typeck_results().expr_ty(self_arg); - let receiver_ty_adjusted = cx.typeck_results().expr_ty_adjusted(self_arg); - let ref_receiver_ty = cx.tcx.mk_ref( - cx.tcx.lifetimes.re_erased, - ty::TypeAndMut { - ty: receiver_ty, - mutbl: Mutability::Not, - }, - ); - receiver_ty_adjusted == ref_receiver_ty - }, - _ => false, +pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<'_>, msrv: &Msrv) { + let Some((adjust, ty)) = is_ref_iterable(cx, self_arg, call_expr) else { + return; }; + if let ty::Array(_, count) = *ty.peel_refs().kind() { + if !ty.is_ref() { + if !msrv.meets(msrvs::ARRAY_INTO_ITERATOR) { + return; + } + } else if count + .try_eval_target_usize(cx.tcx, cx.param_env) + .map_or(true, |x| x > 32) + && !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN) + { + return; + } + } - if !should_lint { + let mut applicability = Applicability::MachineApplicable; + let object = snippet_with_applicability(cx, self_arg.span, "_", &mut applicability); +<<<<<<< HEAD +======= +use rustc_middle::ty::{self, EarlyBinder, TypeAndMut, Ty}; +======= +use rustc_middle::ty::{self, EarlyBinder, Ty, TypeAndMut}; +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) +use rustc_span::sym; + +pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<'_>, msrv: &Msrv) { + let Some((adjust, ty)) = is_ref_iterable(cx, self_arg, call_expr) else { return; + }; + if let ty::Array(_, count) = *ty.peel_refs().kind() { + if !ty.is_ref() { + if !msrv.meets(msrvs::ARRAY_INTO_ITERATOR) { + return; + } + } else if count + .try_eval_target_usize(cx.tcx, cx.param_env) + .map_or(true, |x| x > 32) + && !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN) + { + return; + } } let mut applicability = Applicability::MachineApplicable; let object = snippet_with_applicability(cx, self_arg.span, "_", &mut applicability); - let muta = if method_name == "iter_mut" { "mut " } else { "" }; + let prefix = match adjust { + AdjustKind::None => "", + AdjustKind::Borrow => "&", + AdjustKind::BorrowMut => "&mut ", + AdjustKind::Deref => "*", + AdjustKind::Reborrow => "&*", + AdjustKind::ReborrowMut => "&mut *", + }; +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) span_lint_and_sugg( cx, EXPLICIT_ITER_LOOP, - arg.span, + call_expr.span, "it is more concise to loop over references to containers instead of using explicit \ iteration methods", "to write this more concisely, try", - format!("&{muta}{object}"), +<<<<<<< HEAD +<<<<<<< HEAD + format!("{}{object}", adjust.display()), +======= + format!("{prefix}{object}"), +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= + format!("{}{object}", adjust.display()), +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) applicability, ); } -/// Returns `true` if the type of expr is one that provides `IntoIterator` impls -/// for `&T` and `&mut T`, such as `Vec`. -#[rustfmt::skip] -fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - // no walk_ptrs_ty: calling iter() on a reference can make sense because it - // will allow further borrows afterwards - let ty = cx.typeck_results().expr_ty(e); - is_iterable_array(ty, cx) || - is_type_diagnostic_item(cx, ty, sym::Vec) || - is_type_diagnostic_item(cx, ty, sym::LinkedList) || - is_type_diagnostic_item(cx, ty, sym::HashMap) || - is_type_diagnostic_item(cx, ty, sym::HashSet) || - is_type_diagnostic_item(cx, ty, sym::VecDeque) || - is_type_diagnostic_item(cx, ty, sym::BinaryHeap) || - is_type_diagnostic_item(cx, ty, sym::BTreeMap) || - is_type_diagnostic_item(cx, ty, sym::BTreeSet) +<<<<<<< HEAD +<<<<<<< HEAD +#[derive(Clone, Copy)] +======= +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= +#[derive(Clone, Copy)] +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) +enum AdjustKind { + None, + Borrow, + BorrowMut, + Deref, + Reborrow, + ReborrowMut, } +impl AdjustKind { + fn borrow(mutbl: Mutability) -> Self { + match mutbl { + Mutability::Not => Self::Borrow, + Mutability::Mut => Self::BorrowMut, + } + } -fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { - // IntoIterator is currently only implemented for array sizes <= 32 in rustc - match ty.kind() { - ty::Array(_, n) => n - .try_eval_target_usize(cx.tcx, cx.param_env) - .map_or(false, |val| (0..=32).contains(&val)), - _ => false, + fn auto_borrow(mutbl: AutoBorrowMutability) -> Self { + match mutbl { + AutoBorrowMutability::Not => Self::Borrow, + AutoBorrowMutability::Mut { .. } => Self::BorrowMut, + } + } + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + fn reborrow(mutbl: Mutability) -> Self { + match mutbl { + Mutability::Not => Self::Reborrow, + Mutability::Mut => Self::ReborrowMut, + } + } + + fn auto_reborrow(mutbl: AutoBorrowMutability) -> Self { +<<<<<<< HEAD +======= + fn reborrow(mutbl: AutoBorrowMutability) -> Self { +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + match mutbl { + AutoBorrowMutability::Not => Self::Reborrow, + AutoBorrowMutability::Mut { .. } => Self::ReborrowMut, + } + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + + fn display(self) -> &'static str { + match self { + Self::None => "", + Self::Borrow => "&", + Self::BorrowMut => "&mut ", + Self::Deref => "*", + Self::Reborrow => "&*", + Self::ReborrowMut => "&mut *", + } + } +<<<<<<< HEAD +======= +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) +} + +/// Checks if an `iter` or `iter_mut` call returns `IntoIterator::IntoIter`. Returns how the +/// argument needs to be adjusted. +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +#[expect(clippy::too_many_lines)] +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) +======= +#[expect(clippy::too_many_lines)] +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) +fn is_ref_iterable<'tcx>( + cx: &LateContext<'tcx>, + self_arg: &Expr<'_>, + call_expr: &Expr<'_>, +) -> Option<(AdjustKind, Ty<'tcx>)> { +<<<<<<< HEAD +======= +fn is_ref_iterable<'tcx>(cx: &LateContext<'tcx>, self_arg: &Expr<'_>, call_expr: &Expr<'_>) -> Option<(AdjustKind, Ty<'tcx>)> { +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + let typeck = cx.typeck_results(); + if let Some(trait_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator) + && let Some(fn_id) = typeck.type_dependent_def_id(call_expr.hir_id) + && let sig = cx.tcx.liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder()) + && let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output + && let param_env = cx.tcx.param_env(fn_id) + && implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, []) + && let Some(into_iter_ty) = + make_normalized_projection_with_regions(cx.tcx, param_env, trait_id, sym!(IntoIter), [req_self_ty]) + && let req_res_ty = normalize_with_regions(cx.tcx, param_env, req_res_ty) + && into_iter_ty == req_res_ty + { + let adjustments = typeck.expr_adjustments(self_arg); + let self_ty = typeck.expr_ty(self_arg); + let self_is_copy = is_copy(cx, self_ty); + + if adjustments.is_empty() && self_is_copy { +<<<<<<< HEAD +<<<<<<< HEAD + // Exact type match, already checked earlier + return Some((AdjustKind::None, self_ty)); + } + + let res_ty = cx.tcx.erase_regions(EarlyBinder::bind(req_res_ty) + .subst(cx.tcx, typeck.node_substs(call_expr.hir_id))); +======= + return Some((AdjustKind::None, self_ty)); + } + + let res_ty = cx.tcx.erase_regions(EarlyBinder::bind(req_res_ty).subst(cx.tcx, typeck.node_substs(call_expr.hir_id))); + if !adjustments.is_empty() && self_is_copy { + if implements_trait(cx, self_ty, trait_id, &[]) + && let Some(ty) = make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty]) + && ty == res_ty + { + return Some((AdjustKind::None, self_ty)); + } + } + +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= + // Exact type match, already checked earlier + return Some((AdjustKind::None, self_ty)); + } + + let res_ty = cx.tcx.erase_regions(EarlyBinder::bind(req_res_ty) + .subst(cx.tcx, typeck.node_substs(call_expr.hir_id))); +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + let mutbl = if let ty::Ref(_, _, mutbl) = *req_self_ty.kind() { + Some(mutbl) + } else { + None + }; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + + if !adjustments.is_empty() { + if self_is_copy { + // Using by value won't consume anything + if implements_trait(cx, self_ty, trait_id, &[]) + && let Some(ty) = + make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty]) + && ty == res_ty + { + return Some((AdjustKind::None, self_ty)); + } + } else if let ty::Ref(region, ty, Mutability::Mut) = *self_ty.kind() + && let Some(mutbl) = mutbl + { + // Attempt to reborrow the mutable reference + let self_ty = if mutbl.is_mut() { + self_ty + } else { +<<<<<<< HEAD + Ty::new_ref(cx.tcx,region, TypeAndMut { ty, mutbl }) +======= + cx.tcx.mk_ref(region, TypeAndMut { ty, mutbl }) +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + }; + if implements_trait(cx, self_ty, trait_id, &[]) + && let Some(ty) = + make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty]) + && ty == res_ty + { + return Some((AdjustKind::reborrow(mutbl), self_ty)); + } + } + } +<<<<<<< HEAD + if let Some(mutbl) = mutbl + && !self_ty.is_ref() + { + // Attempt to borrow + let self_ty = Ty::new_ref(cx.tcx,cx.tcx.lifetimes.re_erased, TypeAndMut { +======= +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + if let Some(mutbl) = mutbl + && !self_ty.is_ref() + { + // Attempt to borrow + let self_ty = cx.tcx.mk_ref(cx.tcx.lifetimes.re_erased, TypeAndMut { +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) + ty: self_ty, + mutbl, + }); + if implements_trait(cx, self_ty, trait_id, &[]) + && let Some(ty) = make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty]) + && ty == res_ty + { + return Some((AdjustKind::borrow(mutbl), self_ty)); + } + } + + match adjustments { + [] => Some((AdjustKind::None, self_ty)), +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + &[ + Adjustment { kind: Adjust::Deref(_), ..}, + Adjustment { + kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), + target, + }, + .. + ] => { +<<<<<<< HEAD + if target != self_ty + && implements_trait(cx, target, trait_id, &[]) + && let Some(ty) = + make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target]) + && ty == res_ty + { + Some((AdjustKind::auto_reborrow(mutbl), target)) +======= + &[Adjustment { kind: Adjust::Deref(_), ..}, Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), target }, ..] => { +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + if target != self_ty + && implements_trait(cx, target, trait_id, &[]) + && let Some(ty) = + make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target]) + && ty == res_ty + { +<<<<<<< HEAD + Some((AdjustKind::reborrow(mutbl), target)) +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= + Some((AdjustKind::auto_reborrow(mutbl), target)) +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + } else { + None + } + } + &[Adjustment { kind: Adjust::Deref(_), target }, ..] => { + if is_copy(cx, target) + && implements_trait(cx, target, trait_id, &[]) +<<<<<<< HEAD +<<<<<<< HEAD + && let Some(ty) = + make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target]) +======= + && let Some(ty) = make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target]) +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= + && let Some(ty) = + make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target]) +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + && ty == res_ty + { + Some((AdjustKind::Deref, target)) + } else { + None + } + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + &[ + Adjustment { + kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), + target, + }, + .. + ] => { +<<<<<<< HEAD + if self_ty.is_ref() + && implements_trait(cx, target, trait_id, &[]) + && let Some(ty) = + make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target]) +======= + &[Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), target }, ..] => { + if self_ty.is_ref() + && implements_trait(cx, target, trait_id, &[]) + && let Some(ty) = make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target]) +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= + if self_ty.is_ref() + && implements_trait(cx, target, trait_id, &[]) + && let Some(ty) = + make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target]) +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + && ty == res_ty + { + Some((AdjustKind::auto_borrow(mutbl), target)) + } else { + None + } + } + _ => None, + } + } else { + None } } diff --git a/clippy_lints/src/loops/manual_find.rs b/clippy_lints/src/loops/manual_find.rs index 4bb9936e9cde..0aaa66e6bcee 100644 --- a/clippy_lints/src/loops/manual_find.rs +++ b/clippy_lints/src/loops/manual_find.rs @@ -1,14 +1,14 @@ use super::utils::make_iterator_snippet; use super::MANUAL_FIND; -use clippy_utils::{ - diagnostics::span_lint_and_then, higher, is_res_lang_ctor, path_res, peel_blocks_with_stmt, - source::snippet_with_applicability, ty::implements_trait, -}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::source::snippet_with_applicability; +use clippy_utils::ty::implements_trait; +use clippy_utils::{higher, is_res_lang_ctor, path_res, peel_blocks_with_stmt}; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{ - def::Res, lang_items::LangItem, BindingAnnotation, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind, -}; +use rustc_hir::def::Res; +use rustc_hir::lang_items::LangItem; +use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind}; use rustc_lint::LateContext; use rustc_span::source_map::Span; diff --git a/clippy_lints/src/loops/manual_flatten.rs b/clippy_lints/src/loops/manual_flatten.rs index 1e02a30e35fe..559a2c03f146 100644 --- a/clippy_lints/src/loops/manual_flatten.rs +++ b/clippy_lints/src/loops/manual_flatten.rs @@ -1,9 +1,8 @@ use super::utils::make_iterator_snippet; use super::MANUAL_FLATTEN; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::higher; use clippy_utils::visitors::is_local_used; -use clippy_utils::{path_to_local_id, peel_blocks_with_stmt}; +use clippy_utils::{higher, path_to_local_id, peel_blocks_with_stmt}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; diff --git a/clippy_lints/src/loops/manual_memcpy.rs b/clippy_lints/src/loops/manual_memcpy.rs index c87fc4f90e21..7d1f8ef29c81 100644 --- a/clippy_lints/src/loops/manual_memcpy.rs +++ b/clippy_lints/src/loops/manual_memcpy.rs @@ -15,7 +15,7 @@ use rustc_span::symbol::sym; use std::fmt::Display; use std::iter::Iterator; -/// Checks for for loops that sequentially copy items from one slice-like +/// Checks for `for` loops that sequentially copy items from one slice-like /// object to another. pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, @@ -51,7 +51,7 @@ pub(super) fn check<'tcx>( iter_b = Some(get_assignment(body)); } - let assignments = iter_a.into_iter().flatten().chain(iter_b.into_iter()); + let assignments = iter_a.into_iter().flatten().chain(iter_b); let big_sugg = assignments // The only statements in the for loops can be indexed assignments from @@ -402,7 +402,7 @@ fn get_assignments<'a, 'tcx>( StmtKind::Local(..) | StmtKind::Item(..) => None, StmtKind::Expr(e) | StmtKind::Semi(e) => Some(e), }) - .chain((*expr).into_iter()) + .chain(*expr) .filter(move |e| { if let ExprKind::AssignOp(_, place, _) = e.kind { path_to_local(place).map_or(false, |id| { diff --git a/clippy_lints/src/loops/manual_while_let_some.rs b/clippy_lints/src/loops/manual_while_let_some.rs new file mode 100644 index 000000000000..2b6cbf031bd1 --- /dev/null +++ b/clippy_lints/src/loops/manual_while_let_some.rs @@ -0,0 +1,116 @@ +<<<<<<< HEAD +use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and_then}; +use clippy_utils::source::snippet; +use clippy_utils::{match_def_path, paths, SpanlessEq}; +======= +use clippy_utils::{ + diagnostics::{multispan_sugg_with_applicability, span_lint_and_then}, + match_def_path, paths, + source::snippet, + SpanlessEq, +}; +>>>>>>> e4f5d83fa (Fixed formatting.) +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, Pat, Stmt, StmtKind, UnOp}; +use rustc_lint::LateContext; +use rustc_span::Span; +use std::borrow::Cow; + +use super::MANUAL_WHILE_LET_SOME; + +/// The kind of statement that the `pop()` call appeared in. +/// +/// Depending on whether the value was assigned to a variable or not changes what pattern +/// we use for the suggestion. +#[derive(Copy, Clone)] +enum PopStmt<'hir> { + /// `x.pop().unwrap()` was and assigned to a variable. + /// The pattern of this local variable will be used and the local statement + /// is deleted in the suggestion. + Local(&'hir Pat<'hir>), + /// `x.pop().unwrap()` appeared in an arbitrary expression and was not assigned to a variable. + /// The suggestion will use some placeholder identifier and the `x.pop().unwrap()` expression + /// is replaced with that identifier. + Anonymous, +} + +fn report_lint(cx: &LateContext<'_>, pop_span: Span, pop_stmt_kind: PopStmt<'_>, loop_span: Span, receiver_span: Span) { + span_lint_and_then( + cx, + MANUAL_WHILE_LET_SOME, + pop_span, + "you seem to be trying to pop elements from a `Vec` in a loop", + |diag| { + let (pat, pop_replacement) = match pop_stmt_kind { + PopStmt::Local(pat) => (snippet(cx, pat.span, ".."), String::new()), + PopStmt::Anonymous => (Cow::Borrowed("element"), "element".into()), + }; + + let loop_replacement = format!("while let Some({}) = {}.pop()", pat, snippet(cx, receiver_span, "..")); + multispan_sugg_with_applicability( + diag, + "consider using a `while..let` loop", + Applicability::MachineApplicable, + [(loop_span, loop_replacement), (pop_span, pop_replacement)], + ); + }, + ); +} + +fn match_method_call(cx: &LateContext<'_>, expr: &Expr<'_>, method: &[&str]) -> bool { + if let ExprKind::MethodCall(..) = expr.kind + && let Some(id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) + { + match_def_path(cx, id, method) + } else { + false + } +} + +fn is_vec_pop_unwrap(cx: &LateContext<'_>, expr: &Expr<'_>, is_empty_recv: &Expr<'_>) -> bool { + if (match_method_call(cx, expr, &paths::OPTION_UNWRAP) || match_method_call(cx, expr, &paths::OPTION_EXPECT)) + && let ExprKind::MethodCall(_, unwrap_recv, ..) = expr.kind + && match_method_call(cx, unwrap_recv, &paths::VEC_POP) + && let ExprKind::MethodCall(_, pop_recv, ..) = unwrap_recv.kind + { + // make sure they're the same `Vec` + SpanlessEq::new(cx).eq_expr(pop_recv, is_empty_recv) + } else { + false + } +} + +fn check_local(cx: &LateContext<'_>, stmt: &Stmt<'_>, is_empty_recv: &Expr<'_>, loop_span: Span) { + if let StmtKind::Local(local) = stmt.kind + && let Some(init) = local.init + && is_vec_pop_unwrap(cx, init, is_empty_recv) + { + report_lint(cx, stmt.span, PopStmt::Local(local.pat), loop_span, is_empty_recv.span); + } +} + +fn check_call_arguments(cx: &LateContext<'_>, stmt: &Stmt<'_>, is_empty_recv: &Expr<'_>, loop_span: Span) { + if let StmtKind::Semi(expr) | StmtKind::Expr(expr) = stmt.kind { + if let ExprKind::MethodCall(.., args, _) | ExprKind::Call(_, args) = expr.kind { + let offending_arg = args + .iter() + .find_map(|arg| is_vec_pop_unwrap(cx, arg, is_empty_recv).then_some(arg.span)); + + if let Some(offending_arg) = offending_arg { + report_lint(cx, offending_arg, PopStmt::Anonymous, loop_span, is_empty_recv.span); + } + } + } +} + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, full_cond: &'tcx Expr<'_>, body: &'tcx Expr<'_>, loop_span: Span) { + if let ExprKind::Unary(UnOp::Not, cond) = full_cond.kind + && let ExprKind::MethodCall(_, is_empty_recv, _, _) = cond.kind + && match_method_call(cx, cond, &paths::VEC_IS_EMPTY) + && let ExprKind::Block(body, _) = body.kind + && let Some(stmt) = body.stmts.first() + { + check_local(cx, stmt, is_empty_recv, loop_span); + check_call_arguments(cx, stmt, is_empty_recv, loop_span); + } +} diff --git a/clippy_lints/src/loops/missing_spin_loop.rs b/clippy_lints/src/loops/missing_spin_loop.rs index 8412875b11b7..f3bfe9e927d5 100644 --- a/clippy_lints/src/loops/missing_spin_loop.rs +++ b/clippy_lints/src/loops/missing_spin_loop.rs @@ -43,7 +43,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &' MISSING_SPIN_LOOP, body.span, "busy-waiting loop should at least have a spin loop hint", - "try this", + "try", (if is_no_std_crate(cx) { "{ core::hint::spin_loop() }" } else { diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 610a0233eee1..5f2f7ff0f4db 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -7,6 +7,7 @@ mod iter_next_loop; mod manual_find; mod manual_flatten; mod manual_memcpy; +mod manual_while_let_some; mod missing_spin_loop; mod mut_range_bound; mod needless_range_loop; @@ -19,9 +20,10 @@ mod while_let_loop; mod while_let_on_iterator; use clippy_utils::higher; +use clippy_utils::msrvs::Msrv; use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; use utils::{make_iterator_snippet, IncrementVisitor, InitializeVisitor}; @@ -478,7 +480,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Check for unnecessary `if let` usage in a for loop + /// Checks for unnecessary `if let` usage in a for loop /// where only the `Some` or `Ok` variant of the iterator element is used. /// /// ### Why is this bad? @@ -510,7 +512,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Check for empty spin loops + /// Checks for empty spin loops /// /// ### Why is this bad? /// The loop body should have something like `thread::park()` or at least @@ -546,7 +548,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Check for manual implementations of Iterator::find + /// Checks for manual implementations of Iterator::find /// /// ### Why is this bad? /// It doesn't affect performance, but using `find` is shorter and easier to read. @@ -575,7 +577,76 @@ declare_clippy_lint! { "manual implementation of `Iterator::find`" } +declare_clippy_lint! { + /// ### What it does + /// Looks for loops that check for emptiness of a `Vec` in the condition and pop an element + /// in the body as a separate operation. + /// + /// ### Why is this bad? +<<<<<<< HEAD +<<<<<<< HEAD + /// Such loops can be written in a more idiomatic way by using a while-let loop and directly +======= + /// Such loops can be written in a more idiomatic way by using a while..let loop and directly +>>>>>>> 1d0832529 (move lint to loops, emit proper suggestion, more tests) +======= + /// Such loops can be written in a more idiomatic way by using a while-let loop and directly +>>>>>>> 8d8178f93 (rename lint to `manual_while_let_some`) + /// pattern matching on the return value of `Vec::pop()`. + /// + /// ### Example + /// ```rust + /// let mut numbers = vec![1, 2, 3, 4, 5]; + /// while !numbers.is_empty() { + /// let number = numbers.pop().unwrap(); + /// // use `number` + /// } + /// ``` + /// Use instead: + /// ```rust + /// let mut numbers = vec![1, 2, 3, 4, 5]; + /// while let Some(number) = numbers.pop() { + /// // use `number` + /// } + /// ``` +<<<<<<< HEAD +<<<<<<< HEAD + #[clippy::version = "1.70.0"] +<<<<<<< HEAD +<<<<<<< HEAD +======= + #[clippy::version = "1.71.0"] +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= + #[clippy::version = "1.71.0"] +======= + #[clippy::version = "1.70.0"] +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + pub MANUAL_WHILE_LET_SOME, +======= + pub WHILE_POP_UNWRAP, +>>>>>>> 1d0832529 (move lint to loops, emit proper suggestion, more tests) +======= + pub MANUAL_WHILE_LET_SOME, +>>>>>>> 8d8178f93 (rename lint to `manual_while_let_some`) + style, + "checking for emptiness of a `Vec` in the loop condition and popping an element in the body" +} + +<<<<<<< HEAD +pub struct Loops { + msrv: Msrv, +} +impl Loops { + pub fn new(msrv: Msrv) -> Self { + Self { msrv } + } +} +impl_lint_pass!(Loops => [ +======= declare_lint_pass!(Loops => [ +>>>>>>> e4f5d83fa (Fixed formatting.) MANUAL_MEMCPY, MANUAL_FLATTEN, NEEDLESS_RANGE_LOOP, @@ -594,6 +665,15 @@ declare_lint_pass!(Loops => [ SINGLE_ELEMENT_LOOP, MISSING_SPIN_LOOP, MANUAL_FIND, +<<<<<<< HEAD +<<<<<<< HEAD + MANUAL_WHILE_LET_SOME +======= + WHILE_POP_UNWRAP +>>>>>>> 1d0832529 (move lint to loops, emit proper suggestion, more tests) +======= + MANUAL_WHILE_LET_SOME +>>>>>>> 8d8178f93 (rename lint to `manual_while_let_some`) ]); impl<'tcx> LateLintPass<'tcx> for Loops { @@ -613,7 +693,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops { if body.span.from_expansion() { return; } - check_for_loop(cx, pat, arg, body, expr, span); + self.check_for_loop(cx, pat, arg, body, expr, span); if let ExprKind::Block(block, _) = body.kind { never_loop::check(cx, block, loop_id, span, for_loop.as_ref()); } @@ -640,11 +720,86 @@ impl<'tcx> LateLintPass<'tcx> for Loops { while_let_on_iterator::check(cx, expr); - if let Some(higher::While { condition, body }) = higher::While::hir(expr) { + if let Some(higher::While { condition, body, span }) = higher::While::hir(expr) { while_immutable_condition::check(cx, condition, body); missing_spin_loop::check(cx, condition, body); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + manual_while_let_some::check(cx, condition, body, span); +======= + while_pop_unwrap::check(cx, condition, body); +>>>>>>> bb58083ce (new lint: `while_pop_unwrap`) +======= + while_pop_unwrap::check(cx, condition, body, span); +>>>>>>> 1d0832529 (move lint to loops, emit proper suggestion, more tests) +======= + manual_while_let_some::check(cx, condition, body, span); +>>>>>>> 8d8178f93 (rename lint to `manual_while_let_some`) } } +<<<<<<< HEAD + + extract_msrv_attr!(LateContext); +} + +impl Loops { + fn check_for_loop<'tcx>( + &self, + cx: &LateContext<'tcx>, + pat: &'tcx Pat<'_>, + arg: &'tcx Expr<'_>, + body: &'tcx Expr<'_>, + expr: &'tcx Expr<'_>, + span: Span, + ) { + let is_manual_memcpy_triggered = manual_memcpy::check(cx, pat, arg, body, expr); + if !is_manual_memcpy_triggered { + needless_range_loop::check(cx, pat, arg, body, expr); + explicit_counter_loop::check(cx, pat, arg, body, expr); + } + self.check_for_loop_arg(cx, pat, arg); + for_kv_map::check(cx, pat, arg, body); + mut_range_bound::check(cx, arg, body); + single_element_loop::check(cx, pat, arg, body, expr); + same_item_push::check(cx, pat, arg, body, expr); + manual_flatten::check(cx, pat, arg, body, span); + manual_find::check(cx, pat, arg, body, span, expr); + } + + fn check_for_loop_arg(&self, cx: &LateContext<'_>, _: &Pat<'_>, arg: &Expr<'_>) { + if let ExprKind::MethodCall(method, self_arg, [], _) = arg.kind { +<<<<<<< HEAD +<<<<<<< HEAD + match method.ident.as_str() { + "iter" | "iter_mut" => { + explicit_iter_loop::check(cx, self_arg, arg, &self.msrv); + }, + "into_iter" => { +======= + let method_name = method.ident.as_str(); + // check for looping over x.iter() or x.iter_mut(), could use &x or &mut x + match method_name { +======= + match method.ident.as_str() { +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + "iter" | "iter_mut" => { + explicit_iter_loop::check(cx, self_arg, arg, &self.msrv); + }, + "into_iter" => { +<<<<<<< HEAD + explicit_iter_loop::check(cx, self_arg, arg, method_name, &self.msrv); +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + explicit_into_iter_loop::check(cx, self_arg, arg); + }, + "next" => { + iter_next_loop::check(cx, arg); + }, + _ => {}, + } +======= } fn check_for_loop<'tcx>( @@ -685,6 +840,7 @@ fn check_for_loop_arg(cx: &LateContext<'_>, _: &Pat<'_>, arg: &Expr<'_>) { iter_next_loop::check(cx, arg); }, _ => {}, +>>>>>>> e4f5d83fa (Fixed formatting.) } } } diff --git a/clippy_lints/src/loops/mut_range_bound.rs b/clippy_lints/src/loops/mut_range_bound.rs index 4dae93f6028d..b83d148b5f24 100644 --- a/clippy_lints/src/loops/mut_range_bound.rs +++ b/clippy_lints/src/loops/mut_range_bound.rs @@ -7,7 +7,8 @@ use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, Node, PatKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; -use rustc_middle::{mir::FakeReadCause, ty}; +use rustc_middle::mir::FakeReadCause; +use rustc_middle::ty; use rustc_span::source_map::Span; pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) { diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index f0a1b1dfe562..7da9121fbb38 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -1,5 +1,6 @@ use super::utils::make_iterator_snippet; use super::NEVER_LOOP; +use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::ForLoop; use clippy_utils::source::snippet; @@ -9,14 +10,14 @@ use rustc_lint::LateContext; use rustc_span::Span; use std::iter::{once, Iterator}; -pub(super) fn check( - cx: &LateContext<'_>, - block: &Block<'_>, +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + block: &Block<'tcx>, loop_id: HirId, span: Span, for_loop: Option<&ForLoop<'_>>, ) { - match never_loop_block(block, &mut Vec::new(), loop_id) { + match never_loop_block(cx, block, &mut Vec::new(), loop_id) { NeverLoopResult::AlwaysBreak => { span_lint_and_then(cx, NEVER_LOOP, span, "this loop never actually loops", |diag| { if let Some(ForLoop { @@ -95,7 +96,12 @@ fn combine_branches(b1: NeverLoopResult, b2: NeverLoopResult, ignore_ids: &[HirI } } -fn never_loop_block(block: &Block<'_>, ignore_ids: &mut Vec, main_loop_id: HirId) -> NeverLoopResult { +fn never_loop_block<'tcx>( + cx: &LateContext<'tcx>, + block: &Block<'tcx>, + ignore_ids: &mut Vec, + main_loop_id: HirId, +) -> NeverLoopResult { let iter = block .stmts .iter() @@ -103,10 +109,10 @@ fn never_loop_block(block: &Block<'_>, ignore_ids: &mut Vec, main_loop_id .chain(block.expr.map(|expr| (expr, None))); iter.map(|(e, els)| { - let e = never_loop_expr(e, ignore_ids, main_loop_id); + let e = never_loop_expr(cx, e, ignore_ids, main_loop_id); // els is an else block in a let...else binding els.map_or(e, |els| { - combine_branches(e, never_loop_block(els, ignore_ids, main_loop_id), ignore_ids) + combine_branches(e, never_loop_block(cx, els, ignore_ids, main_loop_id), ignore_ids) }) }) .fold(NeverLoopResult::Otherwise, combine_seq) @@ -122,7 +128,12 @@ fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<(&'tcx Expr<'tcx>, Option<&'t } #[allow(clippy::too_many_lines)] -fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec, main_loop_id: HirId) -> NeverLoopResult { +fn never_loop_expr<'tcx>( + cx: &LateContext<'tcx>, + expr: &Expr<'tcx>, + ignore_ids: &mut Vec, + main_loop_id: HirId, +) -> NeverLoopResult { match expr.kind { ExprKind::Unary(_, e) | ExprKind::Cast(e, _) @@ -130,45 +141,51 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec, main_loop_id: H | ExprKind::Field(e, _) | ExprKind::AddrOf(_, _, e) | ExprKind::Repeat(e, _) - | ExprKind::DropTemps(e) => never_loop_expr(e, ignore_ids, main_loop_id), - ExprKind::Let(let_expr) => never_loop_expr(let_expr.init, ignore_ids, main_loop_id), - ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(&mut es.iter(), ignore_ids, main_loop_id), + | ExprKind::DropTemps(e) => never_loop_expr(cx, e, ignore_ids, main_loop_id), + ExprKind::Let(let_expr) => never_loop_expr(cx, let_expr.init, ignore_ids, main_loop_id), + ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(cx, &mut es.iter(), ignore_ids, main_loop_id), ExprKind::MethodCall(_, receiver, es, _) => never_loop_expr_all( + cx, &mut std::iter::once(receiver).chain(es.iter()), ignore_ids, main_loop_id, ), ExprKind::Struct(_, fields, base) => { - let fields = never_loop_expr_all(&mut fields.iter().map(|f| f.expr), ignore_ids, main_loop_id); + let fields = never_loop_expr_all(cx, &mut fields.iter().map(|f| f.expr), ignore_ids, main_loop_id); if let Some(base) = base { - combine_seq(fields, never_loop_expr(base, ignore_ids, main_loop_id)) + combine_seq(fields, never_loop_expr(cx, base, ignore_ids, main_loop_id)) } else { fields } }, - ExprKind::Call(e, es) => never_loop_expr_all(&mut once(e).chain(es.iter()), ignore_ids, main_loop_id), + ExprKind::Call(e, es) => never_loop_expr_all(cx, &mut once(e).chain(es.iter()), ignore_ids, main_loop_id), ExprKind::Binary(_, e1, e2) | ExprKind::Assign(e1, e2, _) | ExprKind::AssignOp(_, e1, e2) - | ExprKind::Index(e1, e2) => never_loop_expr_all(&mut [e1, e2].iter().copied(), ignore_ids, main_loop_id), + | ExprKind::Index(e1, e2) => never_loop_expr_all(cx, &mut [e1, e2].iter().copied(), ignore_ids, main_loop_id), ExprKind::Loop(b, _, _, _) => { // Break can come from the inner loop so remove them. - absorb_break(never_loop_block(b, ignore_ids, main_loop_id)) + absorb_break(never_loop_block(cx, b, ignore_ids, main_loop_id)) }, ExprKind::If(e, e2, e3) => { - let e1 = never_loop_expr(e, ignore_ids, main_loop_id); - let e2 = never_loop_expr(e2, ignore_ids, main_loop_id); + let e1 = never_loop_expr(cx, e, ignore_ids, main_loop_id); + let e2 = never_loop_expr(cx, e2, ignore_ids, main_loop_id); + // If we know the `if` condition evaluates to `true`, don't check everything past it; it + // should just return whatever's evaluated for `e1` and `e2` since `e3` is unreachable + if let Some(Constant::Bool(true)) = constant(cx, cx.typeck_results(), e) { + return combine_seq(e1, e2); + } let e3 = e3.as_ref().map_or(NeverLoopResult::Otherwise, |e| { - never_loop_expr(e, ignore_ids, main_loop_id) + never_loop_expr(cx, e, ignore_ids, main_loop_id) }); combine_seq(e1, combine_branches(e2, e3, ignore_ids)) }, ExprKind::Match(e, arms, _) => { - let e = never_loop_expr(e, ignore_ids, main_loop_id); + let e = never_loop_expr(cx, e, ignore_ids, main_loop_id); if arms.is_empty() { e } else { - let arms = never_loop_expr_branch(&mut arms.iter().map(|a| a.body), ignore_ids, main_loop_id); + let arms = never_loop_expr_branch(cx, &mut arms.iter().map(|a| a.body), ignore_ids, main_loop_id); combine_seq(e, arms) } }, @@ -176,7 +193,7 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec, main_loop_id: H if l.is_some() { ignore_ids.push(b.hir_id); } - let ret = never_loop_block(b, ignore_ids, main_loop_id); + let ret = never_loop_block(cx, b, ignore_ids, main_loop_id); if l.is_some() { ignore_ids.pop(); } @@ -198,25 +215,30 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec, main_loop_id: H // checks if break targets a block instead of a loop ExprKind::Break(Destination { target_id: Ok(t), .. }, e) if ignore_ids.contains(&t) => e .map_or(NeverLoopResult::IgnoreUntilEnd(t), |e| { - never_loop_expr(e, ignore_ids, main_loop_id) + never_loop_expr(cx, e, ignore_ids, main_loop_id) }), ExprKind::Break(_, e) | ExprKind::Ret(e) => e.as_ref().map_or(NeverLoopResult::AlwaysBreak, |e| { combine_seq( - never_loop_expr(e, ignore_ids, main_loop_id), + never_loop_expr(cx, e, ignore_ids, main_loop_id), NeverLoopResult::AlwaysBreak, ) }), + ExprKind::Become(e) => combine_seq( + never_loop_expr(cx, e, ignore_ids, main_loop_id), + NeverLoopResult::AlwaysBreak, + ), ExprKind::InlineAsm(asm) => asm .operands .iter() .map(|(o, _)| match o { InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => { - never_loop_expr(expr, ignore_ids, main_loop_id) + never_loop_expr(cx, expr, ignore_ids, main_loop_id) }, InlineAsmOperand::Out { expr, .. } => { - never_loop_expr_all(&mut expr.iter().copied(), ignore_ids, main_loop_id) + never_loop_expr_all(cx, &mut expr.iter().copied(), ignore_ids, main_loop_id) }, InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => never_loop_expr_all( + cx, &mut once(*in_expr).chain(out_expr.iter().copied()), ignore_ids, main_loop_id, @@ -226,7 +248,8 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec, main_loop_id: H | InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise, }) .fold(NeverLoopResult::Otherwise, combine_seq), - ExprKind::Yield(_, _) + ExprKind::OffsetOf(_, _) + | ExprKind::Yield(_, _) | ExprKind::Closure { .. } | ExprKind::Path(_) | ExprKind::ConstBlock(_) @@ -235,22 +258,24 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec, main_loop_id: H } } -fn never_loop_expr_all<'a, T: Iterator>>( +fn never_loop_expr_all<'tcx, T: Iterator>>( + cx: &LateContext<'tcx>, es: &mut T, ignore_ids: &mut Vec, main_loop_id: HirId, ) -> NeverLoopResult { - es.map(|e| never_loop_expr(e, ignore_ids, main_loop_id)) + es.map(|e| never_loop_expr(cx, e, ignore_ids, main_loop_id)) .fold(NeverLoopResult::Otherwise, combine_seq) } -fn never_loop_expr_branch<'a, T: Iterator>>( +fn never_loop_expr_branch<'tcx, T: Iterator>>( + cx: &LateContext<'tcx>, e: &mut T, ignore_ids: &mut Vec, main_loop_id: HirId, ) -> NeverLoopResult { e.fold(NeverLoopResult::AlwaysBreak, |a, b| { - combine_branches(a, never_loop_expr(b, ignore_ids, main_loop_id), ignore_ids) + combine_branches(a, never_loop_expr(cx, b, ignore_ids, main_loop_id), ignore_ids) }) } diff --git a/clippy_lints/src/loops/same_item_push.rs b/clippy_lints/src/loops/same_item_push.rs index 9d9341559ac7..f7b3b2358a0b 100644 --- a/clippy_lints/src/loops/same_item_push.rs +++ b/clippy_lints/src/loops/same_item_push.rs @@ -148,7 +148,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SameItemPushVisitor<'a, 'tcx> { } fn visit_block(&mut self, b: &'tcx Block<'_>) { - for stmt in b.stmts.iter() { + for stmt in b.stmts { self.visit_stmt(stmt); } } diff --git a/clippy_lints/src/loops/while_immutable_condition.rs b/clippy_lints/src/loops/while_immutable_condition.rs index d1a1f773f87b..7f24f3c5dc28 100644 --- a/clippy_lints/src/loops/while_immutable_condition.rs +++ b/clippy_lints/src/loops/while_immutable_condition.rs @@ -6,8 +6,7 @@ use if_chain::if_chain; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefIdMap; use rustc_hir::intravisit::{walk_expr, Visitor}; -use rustc_hir::HirIdSet; -use rustc_hir::{Expr, ExprKind, QPath}; +use rustc_hir::{Expr, ExprKind, HirIdSet, QPath}; use rustc_lint::LateContext; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) { diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs index 55989f8a4465..ed6af90ef04a 100644 --- a/clippy_lints/src/loops/while_let_on_iterator.rs +++ b/clippy_lints/src/loops/while_let_on_iterator.rs @@ -1,18 +1,18 @@ use super::WHILE_LET_ON_ITERATOR; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::higher; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::{ - get_enclosing_loop_or_multi_call_closure, is_refutable, is_res_lang_ctor, is_trait_method, visitors::is_res_used, -}; +use clippy_utils::visitors::is_res_used; +use clippy_utils::{get_enclosing_loop_or_multi_call_closure, higher, is_refutable, is_res_lang_ctor, is_trait_method}; use if_chain::if_chain; use rustc_errors::Applicability; +use rustc_hir::def::Res; use rustc_hir::intravisit::{walk_expr, Visitor}; -use rustc_hir::{def::Res, Closure, Expr, ExprKind, HirId, LangItem, Local, Mutability, PatKind, UnOp}; +use rustc_hir::{Closure, Expr, ExprKind, HirId, LangItem, Local, Mutability, PatKind, UnOp}; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::ty::adjustment::Adjust; -use rustc_span::{symbol::sym, Symbol}; +use rustc_span::symbol::sym; +use rustc_span::Symbol; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { let (scrutinee_expr, iter_expr_struct, iter_expr, some_pat, loop_expr) = if_chain! { diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs index 26ae4b409c79..70c5182472aa 100644 --- a/clippy_lints/src/macro_use.rs +++ b/clippy_lints/src/macro_use.rs @@ -8,7 +8,8 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{edition::Edition, sym, Span}; +use rustc_span::edition::Edition; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does @@ -101,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports { }); if !id.is_local(); then { - for kid in cx.tcx.module_children(id).iter() { + for kid in cx.tcx.module_children(id) { if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res { let span = mac_attr.span; let def_path = cx.tcx.def_path_str(mac_id); diff --git a/clippy_lints/src/manual_assert.rs b/clippy_lints/src/manual_assert.rs index ce5d657bcf0e..45ea5aab4c2a 100644 --- a/clippy_lints/src/manual_assert.rs +++ b/clippy_lints/src/manual_assert.rs @@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAssert { }; let cond_sugg = sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par(); let sugg = format!("assert!({not}{cond_sugg}, {format_args_snip});"); - // we show to the user the suggestion without the comments, but when applicating the fix, include the comments in the block + // we show to the user the suggestion without the comments, but when applying the fix, include the comments in the block span_lint_and_then( cx, MANUAL_ASSERT, diff --git a/clippy_lints/src/manual_clamp.rs b/clippy_lints/src/manual_clamp.rs index 440362b96b47..e75666e61f55 100644 --- a/clippy_lints/src/manual_clamp.rs +++ b/clippy_lints/src/manual_clamp.rs @@ -4,21 +4,19 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::implements_trait; use clippy_utils::visitors::is_const_evaluatable; -use clippy_utils::MaybePath; use clippy_utils::{ eq_expr_value, in_constant, is_diag_trait_item, is_trait_method, path_res, path_to_local_id, peel_blocks, - peel_blocks_with_stmt, + peel_blocks_with_stmt, MaybePath, }; use itertools::Itertools; -use rustc_errors::Applicability; -use rustc_errors::Diagnostic; -use rustc_hir::{ - def::Res, Arm, BinOpKind, Block, Expr, ExprKind, Guard, HirId, PatKind, PathSegment, PrimTy, QPath, StmtKind, -}; +use rustc_errors::{Applicability, Diagnostic}; +use rustc_hir::def::Res; +use rustc_hir::{Arm, BinOpKind, Block, Expr, ExprKind, Guard, HirId, PatKind, PathSegment, PrimTy, QPath, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{symbol::sym, Span}; +use rustc_span::symbol::sym; +use rustc_span::Span; use std::ops::Deref; declare_clippy_lint! { diff --git a/clippy_lints/src/manual_float_methods.rs b/clippy_lints/src/manual_float_methods.rs new file mode 100644 index 000000000000..085c73a5f9fb --- /dev/null +++ b/clippy_lints/src/manual_float_methods.rs @@ -0,0 +1,173 @@ +use clippy_utils::consts::{constant, Constant}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::source::snippet_opt; +use clippy_utils::{is_from_proc_macro, path_to_local}; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind}; +use rustc_lint::{LateContext, LateLintPass, Lint, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for manual `is_infinite` reimplementations + /// (i.e., `x == ::INFINITY || x == ::NEG_INFINITY`). + /// + /// ### Why is this bad? + /// The method `is_infinite` is shorter and more readable. + /// + /// ### Example + /// ```rust + /// # let x = 1.0f32; + /// if x == f32::INFINITY || x == f32::NEG_INFINITY {} + /// ``` + /// Use instead: + /// ```rust + /// # let x = 1.0f32; + /// if x.is_infinite() {} + /// ``` + #[clippy::version = "1.72.0"] + pub MANUAL_IS_INFINITE, + style, + "use dedicated method to check if a float is infinite" +} +declare_clippy_lint! { + /// ### What it does + /// Checks for manual `is_finite` reimplementations + /// (i.e., `x != ::INFINITY && x != ::NEG_INFINITY`). + /// + /// ### Why is this bad? + /// The method `is_finite` is shorter and more readable. + /// + /// ### Example + /// ```rust + /// # let x = 1.0f32; + /// if x != f32::INFINITY && x != f32::NEG_INFINITY {} + /// if x.abs() < f32::INFINITY {} + /// ``` + /// Use instead: + /// ```rust + /// # let x = 1.0f32; + /// if x.is_finite() {} + /// if x.is_finite() {} + /// ``` + #[clippy::version = "1.72.0"] + pub MANUAL_IS_FINITE, + style, + "use dedicated method to check if a float is finite" +} +declare_lint_pass!(ManualFloatMethods => [MANUAL_IS_INFINITE, MANUAL_IS_FINITE]); + +#[derive(Clone, Copy)] +enum Variant { + ManualIsInfinite, + ManualIsFinite, +} + +impl Variant { + pub fn lint(self) -> &'static Lint { + match self { + Self::ManualIsInfinite => MANUAL_IS_INFINITE, + Self::ManualIsFinite => MANUAL_IS_FINITE, + } + } + + pub fn msg(self) -> &'static str { + match self { + Self::ManualIsInfinite => "manually checking if a float is infinite", + Self::ManualIsFinite => "manually checking if a float is finite", + } + } +} + +impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { + if !in_external_macro(cx.sess(), expr.span) + && (!cx.param_env.is_const() || cx.tcx.features().active(sym!(const_float_classify))) + && let ExprKind::Binary(kind, lhs, rhs) = expr.kind + && let ExprKind::Binary(lhs_kind, lhs_lhs, lhs_rhs) = lhs.kind + && let ExprKind::Binary(rhs_kind, rhs_lhs, rhs_rhs) = rhs.kind + // Checking all possible scenarios using a function would be a hopeless task, as we have + // 16 possible alignments of constants/operands. For now, let's use `partition`. + && let (operands, constants) = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs] + .into_iter() + .partition::>, _>(|i| path_to_local(i).is_some()) + && let [first, second] = &*operands + && let Some([const_1, const_2]) = constants + .into_iter() + .map(|i| constant(cx, cx.typeck_results(), i)) + .collect::>>() + .as_deref() + && path_to_local(first).is_some_and(|f| path_to_local(second).is_some_and(|s| f == s)) + // The actual infinity check, we also allow `NEG_INFINITY` before` INFINITY` just in + // case somebody does that for some reason + && (is_infinity(const_1) && is_neg_infinity(const_2) + || is_neg_infinity(const_1) && is_infinity(const_2)) + && !is_from_proc_macro(cx, expr) + && let Some(local_snippet) = snippet_opt(cx, first.span) + { + let variant = match (kind.node, lhs_kind.node, rhs_kind.node) { + (BinOpKind::Or, BinOpKind::Eq, BinOpKind::Eq) => Variant::ManualIsInfinite, + (BinOpKind::And, BinOpKind::Ne, BinOpKind::Ne) => Variant::ManualIsFinite, + _ => return, + }; + + span_lint_and_then( + cx, + variant.lint(), + expr.span, + variant.msg(), + |diag| { + match variant { + Variant::ManualIsInfinite => { + diag.span_suggestion( + expr.span, + "use the dedicated method instead", + format!("{local_snippet}.is_infinite()"), + Applicability::MachineApplicable, + ); + }, + Variant::ManualIsFinite => { + // TODO: There's probably some better way to do this, i.e., create + // multiple suggestions with notes between each of them + diag.span_suggestion_verbose( + expr.span, + "use the dedicated method instead", + format!("{local_snippet}.is_finite()"), + Applicability::MaybeIncorrect, + ) + .span_suggestion_verbose( + expr.span, + "this will alter how it handles NaN; if that is a problem, use instead", + format!("{local_snippet}.is_finite() || {local_snippet}.is_nan()"), + Applicability::MaybeIncorrect, + ) + .span_suggestion_verbose( + expr.span, + "or, for conciseness", + format!("!{local_snippet}.is_infinite()"), + Applicability::MaybeIncorrect, + ); + }, + } + }, + ); + } + } +} + +fn is_infinity(constant: &Constant<'_>) -> bool { + match constant { + Constant::F32(float) => *float == f32::INFINITY, + Constant::F64(float) => *float == f64::INFINITY, + _ => false, + } +} + +fn is_neg_infinity(constant: &Constant<'_>) -> bool { + match constant { + Constant::F32(float) => *float == f32::NEG_INFINITY, + Constant::F64(float) => *float == f64::NEG_INFINITY, + _ => false, + } +} diff --git a/clippy_lints/src/manual_is_ascii_check.rs b/clippy_lints/src/manual_is_ascii_check.rs index 31264261f5db..f264424470da 100644 --- a/clippy_lints/src/manual_is_ascii_check.rs +++ b/clippy_lints/src/manual_is_ascii_check.rs @@ -1,12 +1,16 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::macros::root_macro_call; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::{diagnostics::span_lint_and_sugg, higher, in_constant, macros::root_macro_call, sugg::Sugg}; +use clippy_utils::sugg::Sugg; +use clippy_utils::{higher, in_constant}; use rustc_ast::ast::RangeLimits; use rustc_ast::LitKind::{Byte, Char}; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, PatKind, RangeEnd}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{def_id::DefId, sym, Span}; +use rustc_span::def_id::DefId; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/manual_let_else.rs b/clippy_lints/src/manual_let_else.rs index 98e698c6c2a0..64d431e152cd 100644 --- a/clippy_lints/src/manual_let_else.rs +++ b/clippy_lints/src/manual_let_else.rs @@ -1,22 +1,22 @@ +use crate::question_mark::{QuestionMark, QUESTION_MARK}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::IfLetOrMatch; -use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::peel_blocks; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::{Descend, Visitable}; -use if_chain::if_chain; -use rustc_data_structures::fx::FxHashSet; +use clippy_utils::{is_lint_allowed, msrvs, pat_and_expr_can_be_question_mark, peel_blocks}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::{Expr, ExprKind, HirId, ItemId, Local, MatchSource, Pat, PatKind, QPath, Stmt, StmtKind, Ty}; -use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_lint::{LateContext, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::symbol::sym; +use rustc_session::declare_tool_lint; +use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use serde::Deserialize; use std::ops::ControlFlow; +use std::slice; declare_clippy_lint! { /// ### What it does @@ -38,7 +38,6 @@ declare_clippy_lint! { /// Could be written: /// /// ```rust - /// # #![feature(let_else)] /// # fn main () { /// # let w = Some(0); /// let Some(v) = w else { return }; @@ -50,6 +49,7 @@ declare_clippy_lint! { "manual implementation of a let...else statement" } +<<<<<<< HEAD pub struct ManualLetElse { msrv: Msrv, matches_behaviour: MatchLintBehaviour, @@ -69,29 +69,122 @@ impl_lint_pass!(ManualLetElse => [MANUAL_LET_ELSE]); impl<'tcx> LateLintPass<'tcx> for ManualLetElse { fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) { - let if_let_or_match = if_chain! { - if self.msrv.meets(msrvs::LET_ELSE); - if !in_external_macro(cx.sess(), stmt.span); - if let StmtKind::Local(local) = stmt.kind; - if let Some(init) = local.init; - if local.els.is_none(); - if local.ty.is_none(); - if init.span.ctxt() == stmt.span.ctxt(); - if let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init); - then { - if_let_or_match - } else { - return; - } - }; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4931f4549 (Split if conditions by its semantics) +======= +impl<'tcx> QuestionMark { + pub(crate) fn check_manual_let_else(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) { +>>>>>>> 20dfaba03 (Put into one pass) + if !self.msrv.meets(msrvs::LET_ELSE) || in_external_macro(cx.sess(), stmt.span) { + return; + } + + if let StmtKind::Local(local) = stmt.kind && +<<<<<<< HEAD +======= + if self.msrv.meets(msrvs::LET_ELSE) && + !in_external_macro(cx.sess(), stmt.span) && + let StmtKind::Local(local) = stmt.kind && +>>>>>>> a408e7609 (Suggest the correct variable name for `manual_let_else`) +======= +>>>>>>> 4931f4549 (Split if conditions by its semantics) + let Some(init) = local.init && + local.els.is_none() && + local.ty.is_none() && + init.span.ctxt() == stmt.span.ctxt() && +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 83a4b0987 (Fix formatting of if let chain) + let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init) + { + match if_let_or_match { +<<<<<<< HEAD + IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else) => if_chain! { +<<<<<<< HEAD +<<<<<<< HEAD + if let Some(ident_map) = expr_simple_identity_map(local.pat, let_pat, if_then); + if let Some(if_else) = if_else; + if expr_diverges(cx, if_else); + if pat_and_expr_can_be_question_mark(cx, let_pat, if_else).is_none(); + then { +======= + IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else) => { + if + let Some(ident_map) = expr_simple_identity_map(local.pat, let_pat, if_then) && + let Some(if_else) = if_else && + expr_diverges(cx, if_else) && + let qm_allowed = is_lint_allowed(cx, QUESTION_MARK, stmt.hir_id) && + (qm_allowed || pat_and_expr_can_be_question_mark(cx, let_pat, if_else).is_none()) + { +>>>>>>> 6990eaa97 (Don't suppress manual_let_else if question_mark is allowed) + emit_manual_let_else(cx, stmt.span, if_let_expr, &ident_map, let_pat, if_else); +======= + if expr_is_simple_identity(let_pat, if_then); + if let Some(if_else) = if_else; + if expr_diverges(cx, if_else); + then { + emit_manual_let_else(cx, stmt.span, if_let_expr, local.pat, let_pat, if_else); +>>>>>>> 83a4b0987 (Fix formatting of if let chain) +======= + if let Some(ident_map) = expr_simple_identity_map(local.pat, let_pat, if_then); + if let Some(if_else) = if_else; + if expr_diverges(cx, if_else); + then { + emit_manual_let_else(cx, stmt.span, if_let_expr, &ident_map, let_pat, if_else); +>>>>>>> 86d57b7bd (Support multi-binding situations as well as tuple patterns) + } + }, + IfLetOrMatch::Match(match_expr, arms, source) => { + if self.matches_behaviour == MatchLintBehaviour::Never { + return; + } + if source != MatchSource::Normal { + return; + } + // Any other number than two arms doesn't (necessarily) + // have a trivial mapping to let else. + if arms.len() != 2 { + return; + } + // Guards don't give us an easy mapping either + if arms.iter().any(|arm| arm.guard.is_some()) { + return; + } + let check_types = self.matches_behaviour == MatchLintBehaviour::WellKnownTypes; + let diverging_arm_opt = arms + .iter() + .enumerate() + .find(|(_, arm)| expr_diverges(cx, arm.body) && pat_allowed_for_else(cx, arm.pat, check_types)); + let Some((idx, diverging_arm)) = diverging_arm_opt else { return; }; + // If the non-diverging arm is the first one, its pattern can be reused in a let/else statement. + // However, if it arrives in second position, its pattern may cover some cases already covered + // by the diverging one. + // TODO: accept the non-diverging arm as a second position if patterns are disjointed. + if idx == 0 { + return; + } + let pat_arm = &arms[1 - idx]; +<<<<<<< HEAD +<<<<<<< HEAD + let Some(ident_map) = expr_simple_identity_map(local.pat, pat_arm.pat, pat_arm.body) else { + return + }; + emit_manual_let_else(cx, stmt.span, match_expr, &ident_map, pat_arm.pat, diverging_arm.body); + }, + } +======= + let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init) { match if_let_or_match { IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else) => if_chain! { if expr_is_simple_identity(let_pat, if_then); if let Some(if_else) = if_else; if expr_diverges(cx, if_else); then { - emit_manual_let_else(cx, stmt.span, if_let_expr, let_pat, if_else); + emit_manual_let_else(cx, stmt.span, if_let_expr, local.pat, let_pat, if_else); } }, IfLetOrMatch::Match(match_expr, arms, source) => { @@ -101,7 +194,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualLetElse { if source != MatchSource::Normal { return; } - // Any other number than two arms doesn't (neccessarily) + // Any other number than two arms doesn't (necessarily) // have a trivial mapping to let else. if arms.len() != 2 { return; @@ -116,27 +209,49 @@ impl<'tcx> LateLintPass<'tcx> for ManualLetElse { .enumerate() .find(|(_, arm)| expr_diverges(cx, arm.body) && pat_allowed_for_else(cx, arm.pat, check_types)); let Some((idx, diverging_arm)) = diverging_arm_opt else { return; }; - // If the non-diverging arm is the first one, its pattern can be reused in a let/else statement. - // However, if it arrives in second position, its pattern may cover some cases already covered - // by the diverging one. - // TODO: accept the non-diverging arm as a second position if patterns are disjointed. - if idx == 0 { - return; - } let pat_arm = &arms[1 - idx]; if !expr_is_simple_identity(pat_arm.pat, pat_arm.body) { return; } - emit_manual_let_else(cx, stmt.span, match_expr, pat_arm.pat, diverging_arm.body); + emit_manual_let_else(cx, stmt.span, match_expr, local.pat, pat_arm.pat, diverging_arm.body); }, } - } +>>>>>>> a408e7609 (Suggest the correct variable name for `manual_let_else`) +======= + if !expr_is_simple_identity(pat_arm.pat, pat_arm.body) { + return; + } +======= + let Some(ident_map) = expr_simple_identity_map(local.pat, pat_arm.pat, pat_arm.body) else { + return + }; +>>>>>>> 86d57b7bd (Support multi-binding situations as well as tuple patterns) - extract_msrv_attr!(LateContext); + emit_manual_let_else(cx, stmt.span, match_expr, &ident_map, pat_arm.pat, diverging_arm.body); + }, + } +>>>>>>> 83a4b0987 (Fix formatting of if let chain) + }; + } } -fn emit_manual_let_else(cx: &LateContext<'_>, span: Span, expr: &Expr<'_>, pat: &Pat<'_>, else_body: &Expr<'_>) { +fn emit_manual_let_else( + cx: &LateContext<'_>, + span: Span, + expr: &Expr<'_>, +<<<<<<< HEAD +<<<<<<< HEAD + ident_map: &FxHashMap>, +======= + local: &Pat<'_>, +>>>>>>> a408e7609 (Suggest the correct variable name for `manual_let_else`) +======= + ident_map: &FxHashMap>, +>>>>>>> 86d57b7bd (Support multi-binding situations as well as tuple patterns) + pat: &Pat<'_>, + else_body: &Expr<'_>, +) { span_lint_and_then( cx, MANUAL_LET_ELSE, @@ -144,13 +259,26 @@ fn emit_manual_let_else(cx: &LateContext<'_>, span: Span, expr: &Expr<'_>, pat: "this could be rewritten as `let...else`", |diag| { // This is far from perfect, for example there needs to be: +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + // * renamings of the bindings for many `PatKind`s like slices, etc. + // * limitations in the existing replacement algorithms +======= // * mut additions for the bindings - // * renamings of the bindings + // * renamings of the bindings for `PatKind::Or` +>>>>>>> a408e7609 (Suggest the correct variable name for `manual_let_else`) +======= + // * tracking for multi-binding cases: let (foo, bar) = if let (Some(foo), Ok(bar)) = ... + // * renamings of the bindings for many `PatKind`s like structs, slices, etc. +>>>>>>> ef38662d0 (Some improvements to the manual_let_else lint suggestions) +======= + // * renamings of the bindings for many `PatKind`s like slices, etc. + // * limitations in the existing replacement algorithms +>>>>>>> f53840270 (Support struct patterns) // * unused binding collision detection with existing ones - // * putting patterns with at the top level | inside () // for this to be machine applicable. let mut app = Applicability::HasPlaceholders; - let (sn_pat, _) = snippet_with_context(cx, pat.span, span.ctxt(), "", &mut app); let (sn_expr, _) = snippet_with_context(cx, expr.span, span.ctxt(), "", &mut app); let (sn_else, _) = snippet_with_context(cx, else_body.span, span.ctxt(), "", &mut app); @@ -159,17 +287,307 @@ fn emit_manual_let_else(cx: &LateContext<'_>, span: Span, expr: &Expr<'_>, pat: } else { format!("{{ {sn_else} }}") }; - let sn_bl = if matches!(pat.kind, PatKind::Or(..)) { - format!("({sn_pat})") - } else { - sn_pat.into_owned() +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + let sn_bl = replace_in_pattern(cx, span, ident_map, pat, &mut app, true); +======= + let sn_bl = match pat.kind { + PatKind::Or(..) => { + let (sn_pat, _) = snippet_with_context(cx, pat.span, span.ctxt(), "", &mut app); + format!("({sn_pat})") + }, + // Replace the variable name iff `TupleStruct` has one argument like `Variant(v)`. + PatKind::TupleStruct(ref w, args, ..) if args.len() == 1 => { + let sn_wrapper = cx.sess().source_map().span_to_snippet(w.span()).unwrap_or_default(); + let (sn_inner, _) = snippet_with_context(cx, local.span, span.ctxt(), "", &mut app); + format!("{sn_wrapper}({sn_inner})") + }, + _ => { + let (sn_pat, _) = snippet_with_context(cx, pat.span, span.ctxt(), "", &mut app); + sn_pat.into_owned() + }, }; +>>>>>>> a408e7609 (Suggest the correct variable name for `manual_let_else`) +======= + let sn_bl = replace_in_pattern(cx, span, local, pat, &mut app); +>>>>>>> ef38662d0 (Some improvements to the manual_let_else lint suggestions) +======= + let sn_bl = replace_in_pattern(cx, span, local, pat, &mut app, true); +>>>>>>> 0a7366897 (manual_let_else: only add () around PatKind::Or at the top level) +======= + let sn_bl = replace_in_pattern(cx, span, ident_map, pat, &mut app, true); +>>>>>>> 86d57b7bd (Support multi-binding situations as well as tuple patterns) let sugg = format!("let {sn_bl} = {sn_expr} else {else_bl};"); diag.span_suggestion(span, "consider writing", sugg, app); }, ); } +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 86d57b7bd (Support multi-binding situations as well as tuple patterns) +======= +/// Returns whether the given let pattern and else body can be turned into a question mark +/// +/// For this example: +/// ```ignore +/// let FooBar { a, b } = if let Some(a) = ex { a } else { return None }; +/// ``` +/// We get as parameters: +/// ```ignore +/// pat: Some(a) +/// else_body: return None +/// ``` + +/// And for this example: +/// ```ignore +/// let Some(FooBar { a, b }) = ex else { return None }; +/// ``` +/// We get as parameters: +/// ```ignore +/// pat: Some(FooBar { a, b }) +/// else_body: return None +/// ``` + +/// We output `Some(a)` in the first instance, and `Some(FooBar { a, b })` in the second, because +/// the question mark operator is applicable here. Callers have to check whether we are in a +/// constant or not. +pub fn pat_and_expr_can_be_question_mark<'a, 'hir>( + cx: &LateContext<'_>, + pat: &'a Pat<'hir>, + else_body: &Expr<'_>, +) -> Option<&'a Pat<'hir>> { + if let PatKind::TupleStruct(pat_path, [inner_pat], _) = pat.kind && + is_res_lang_ctor(cx, cx.qpath_res(&pat_path, pat.hir_id), OptionSome) && + !is_refutable(cx, inner_pat) && + let else_body = peel_blocks(else_body) && + let ExprKind::Ret(Some(ret_val)) = else_body.kind && + let ExprKind::Path(ret_path) = ret_val.kind && + is_res_lang_ctor(cx, cx.qpath_res(&ret_path, ret_val.hir_id), OptionNone) + { + Some(inner_pat) + } else { + None + } +} + +>>>>>>> 86391abc7 (Don't lint manual_let_else in cases where the question mark operator would work) +======= +>>>>>>> 20dfaba03 (Put into one pass) +/// Replaces the locals in the pattern +/// +/// For this example: +/// +/// ```ignore +/// let (a, FooBar { b, c }) = if let Bar { Some(a_i), b_i } = ex { (a_i, b_i) } else { return }; +/// ``` +/// +/// We have: +/// +/// ```ignore +/// pat: Bar { Some(a_i), b_i } +/// ident_map: (a_i) -> (a), (b_i) -> (FooBar { b, c }) +/// ``` +/// +/// We return: +/// +/// ```ignore +/// Bar { Some(a), b_i: FooBar { b, c } } +/// ``` +<<<<<<< HEAD +fn replace_in_pattern( + cx: &LateContext<'_>, + span: Span, + ident_map: &FxHashMap>, + pat: &Pat<'_>, + app: &mut Applicability, + top_level: bool, +) -> String { + // We put a labeled block here so that we can implement the fallback in this function. + // As the function has multiple call sites, implementing the fallback via an Option + // return type and unwrap_or_else would cause repetition. Similarly, the function also + // invokes the fall back multiple times. + 'a: { + // If the ident map is empty, there is no replacement to do. + // The code following this if assumes a non-empty ident_map. + if ident_map.is_empty() { + break 'a; + } + + match pat.kind { + PatKind::Binding(_ann, _id, binding_name, opt_subpt) => { + let Some(pat_to_put) = ident_map.get(&binding_name.name) else { break 'a }; + let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app); + if let Some(subpt) = opt_subpt { + let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false); + return format!("{sn_ptp} @ {subpt}"); + } + return sn_ptp.to_string(); + }, + PatKind::Or(pats) => { + let patterns = pats + .iter() + .map(|pat| replace_in_pattern(cx, span, ident_map, pat, app, false)) + .collect::>(); + let or_pat = patterns.join(" | "); + if top_level { + return format!("({or_pat})"); + } + return or_pat; + }, + PatKind::Struct(path, fields, has_dot_dot) => { + let fields = fields + .iter() + .map(|fld| { + if let PatKind::Binding(_, _, name, None) = fld.pat.kind && + let Some(pat_to_put) = ident_map.get(&name.name) + { + let (sn_fld_name, _) = snippet_with_context(cx, fld.ident.span, span.ctxt(), "", app); + let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app); + // TODO: this is a bit of a hack, but it does its job. Ideally, we'd check if pat_to_put is + // a PatKind::Binding but that is also hard to get right. + if sn_fld_name == sn_ptp { + // Field init shorthand + return format!("{sn_fld_name}"); + } + return format!("{sn_fld_name}: {sn_ptp}"); + } + let (sn_fld, _) = snippet_with_context(cx, fld.span, span.ctxt(), "", app); + sn_fld.into_owned() + }) + .collect::>(); + let fields_string = fields.join(", "); + + let dot_dot_str = if has_dot_dot { " .." } else { "" }; + let (sn_pth, _) = snippet_with_context(cx, path.span(), span.ctxt(), "", app); + return format!("{sn_pth} {{ {fields_string}{dot_dot_str} }}"); + }, + // Replace the variable name iff `TupleStruct` has one argument like `Variant(v)`. + PatKind::TupleStruct(ref w, args, dot_dot_pos) => { + let mut args = args + .iter() + .map(|pat| replace_in_pattern(cx, span, ident_map, pat, app, false)) + .collect::>(); + if let Some(pos) = dot_dot_pos.as_opt_usize() { + args.insert(pos, "..".to_owned()); + } + let args = args.join(", "); + let sn_wrapper = cx.sess().source_map().span_to_snippet(w.span()).unwrap_or_default(); + return format!("{sn_wrapper}({args})"); + }, + PatKind::Tuple(args, dot_dot_pos) => { + let mut args = args + .iter() + .map(|pat| replace_in_pattern(cx, span, ident_map, pat, app, false)) + .collect::>(); + if let Some(pos) = dot_dot_pos.as_opt_usize() { + args.insert(pos, "..".to_owned()); + } + let args = args.join(", "); + return format!("({args})"); + }, + _ => {}, + } +======= +// replaces the locals in the pattern +======= +>>>>>>> 86d57b7bd (Support multi-binding situations as well as tuple patterns) +fn replace_in_pattern( + cx: &LateContext<'_>, + span: Span, + ident_map: &FxHashMap>, + pat: &Pat<'_>, + app: &mut Applicability, + top_level: bool, +) -> String { + // We put a labeled block here so that we can implement the fallback in this function. + // As the function has multiple call sites, implementing the fallback via an Option + // return type and unwrap_or_else would cause repetition. Similarly, the function also + // invokes the fall back multiple times. + 'a: { + // If the ident map is empty, there is no replacement to do. + // The code following this if assumes a non-empty ident_map. + if ident_map.is_empty() { + break 'a; + } + + match pat.kind { + PatKind::Binding(_ann, _id, binding_name, opt_subpt) => { + let Some(pat_to_put) = ident_map.get(&binding_name.name) else { break 'a }; + let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app); + if let Some(subpt) = opt_subpt { + let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false); + return format!("{sn_ptp} @ {subpt}"); + } + return sn_ptp.to_string(); + }, + PatKind::Or(pats) => { + let patterns = pats + .iter() + .map(|pat| replace_in_pattern(cx, span, ident_map, pat, app, false)) + .collect::>(); + let or_pat = patterns.join(" | "); + if top_level { + return format!("({or_pat})"); + } + return or_pat; +<<<<<<< HEAD + } + }, + // Replace the variable name iff `TupleStruct` has one argument like `Variant(v)`. + PatKind::TupleStruct(ref w, args, dot_dot_pos) => { + let mut args = args + .iter() + .map(|pat| replace_in_pattern(cx, span, local, pat, app, false)) + .collect::>(); + if let Some(pos) = dot_dot_pos.as_opt_usize() { + args.insert(pos, "..".to_owned()); + } + let args = args.join(", "); + let sn_wrapper = cx.sess().source_map().span_to_snippet(w.span()).unwrap_or_default(); + return format!("{sn_wrapper}({args})"); + }, + _ => {}, +>>>>>>> ef38662d0 (Some improvements to the manual_let_else lint suggestions) +======= + }, + // Replace the variable name iff `TupleStruct` has one argument like `Variant(v)`. + PatKind::TupleStruct(ref w, args, dot_dot_pos) => { + let mut args = args + .iter() + .map(|pat| replace_in_pattern(cx, span, ident_map, pat, app, false)) + .collect::>(); + if let Some(pos) = dot_dot_pos.as_opt_usize() { + args.insert(pos, "..".to_owned()); + } + let args = args.join(", "); + let sn_wrapper = cx.sess().source_map().span_to_snippet(w.span()).unwrap_or_default(); + return format!("{sn_wrapper}({args})"); + }, + PatKind::Tuple(args, dot_dot_pos) => { + let mut args = args + .iter() + .map(|pat| replace_in_pattern(cx, span, ident_map, pat, app, false)) + .collect::>(); + if let Some(pos) = dot_dot_pos.as_opt_usize() { + args.insert(pos, "..".to_owned()); + } + let args = args.join(", "); + return format!("({args})"); + }, + _ => {}, + } +>>>>>>> 86d57b7bd (Support multi-binding situations as well as tuple patterns) + } + let (sn_pat, _) = snippet_with_context(cx, pat.span, span.ctxt(), "", app); + sn_pat.into_owned() +} + /// Check whether an expression is divergent. May give false negatives. fn expr_diverges(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { struct V<'cx, 'tcx> { @@ -308,37 +726,74 @@ fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: boo !has_disallowed } -/// Checks if the passed block is a simple identity referring to bindings created by the pattern -fn expr_is_simple_identity(pat: &'_ Pat<'_>, expr: &'_ Expr<'_>) -> bool { - // We support patterns with multiple bindings and tuples, like: - // let ... = if let (Some(foo), bar) = g() { (foo, bar) } else { ... } +/// Checks if the passed block is a simple identity referring to bindings created by the pattern, +/// and if yes, returns a mapping between the relevant sub-pattern and the identifier it corresponds +/// to. +/// +/// We support patterns with multiple bindings and tuples, e.g.: +/// +/// ```ignore +/// let (foo_o, bar_o) = if let (Some(foo), bar) = g() { (foo, bar) } else { ... } +/// ``` +/// +/// The expected params would be: +/// +/// ```ignore +/// local_pat: (foo_o, bar_o) +/// let_pat: (Some(foo), bar) +/// expr: (foo, bar) +/// ``` +/// +/// We build internal `sub_pats` so that it looks like `[foo_o, bar_o]` and `paths` so that it looks +/// like `[foo, bar]`. Then we turn that into `FxHashMap [(foo) -> (foo_o), (bar) -> (bar_o)]` which +/// we return. +fn expr_simple_identity_map<'a, 'hir>( + local_pat: &'a Pat<'hir>, + let_pat: &'_ Pat<'hir>, + expr: &'_ Expr<'hir>, +) -> Option>> { let peeled = peel_blocks(expr); - let paths = match peeled.kind { - ExprKind::Tup(exprs) | ExprKind::Array(exprs) => exprs, - ExprKind::Path(_) => std::slice::from_ref(peeled), - _ => return false, + let (sub_pats, paths) = match (local_pat.kind, peeled.kind) { + (PatKind::Tuple(pats, _), ExprKind::Tup(exprs)) | (PatKind::Slice(pats, ..), ExprKind::Array(exprs)) => { + (pats, exprs) + }, + (_, ExprKind::Path(_)) => (slice::from_ref(local_pat), slice::from_ref(peeled)), + _ => return None, }; + + // There is some length mismatch, which indicates usage of .. in the patterns above e.g.: + // let (a, ..) = if let [a, b, _c] = ex { (a, b) } else { ... }; + // We bail in these cases as they should be rare. + if paths.len() != sub_pats.len() { + return None; + } + let mut pat_bindings = FxHashSet::default(); - pat.each_binding_or_first(&mut |_ann, _hir_id, _sp, ident| { + let_pat.each_binding_or_first(&mut |_ann, _hir_id, _sp, ident| { pat_bindings.insert(ident); }); if pat_bindings.len() < paths.len() { - return false; + // This rebinds some bindings from the outer scope, or it repeats some copy-able bindings multiple + // times. We don't support these cases so we bail here. E.g.: + // let foo = 0; + // let (new_foo, bar, bar_copied) = if let Some(bar) = Some(0) { (foo, bar, bar) } else { .. }; + return None; } - for path in paths { - if_chain! { - if let ExprKind::Path(QPath::Resolved(_ty, path)) = path.kind; - if let [path_seg] = path.segments; - then { - if !pat_bindings.remove(&path_seg.ident) { - return false; - } - } else { - return false; + let mut ident_map = FxHashMap::default(); + for (sub_pat, path) in sub_pats.iter().zip(paths.iter()) { + if let ExprKind::Path(QPath::Resolved(_ty, path)) = path.kind && + let [path_seg] = path.segments + { + let ident = path_seg.ident; + if !pat_bindings.remove(&ident) { + return None; } + ident_map.insert(ident.name, sub_pat); + } else { + return None; } } - true + Some(ident_map) } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize)] diff --git a/clippy_lints/src/manual_range_patterns.rs b/clippy_lints/src/manual_range_patterns.rs new file mode 100644 index 000000000000..39d8b20d38d0 --- /dev/null +++ b/clippy_lints/src/manual_range_patterns.rs @@ -0,0 +1,126 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use rustc_ast::LitKind; +use rustc_data_structures::fx::FxHashSet; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, PatKind, RangeEnd, UnOp}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// Looks for combined OR patterns that are all contained in a specific range, + /// e.g. `6 | 4 | 5 | 9 | 7 | 8` can be rewritten as `4..=9`. + /// + /// ### Why is this bad? + /// Using an explicit range is more concise and easier to read. + /// + /// ### Known issues + /// This lint intentionally does not handle numbers greater than `i128::MAX` for `u128` literals + /// in order to support negative numbers. + /// + /// ### Example + /// ```rust + /// let x = 6; + /// let foo = matches!(x, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10); + /// ``` + /// Use instead: + /// ```rust + /// let x = 6; + /// let foo = matches!(x, 1..=10); + /// ``` + #[clippy::version = "1.72.0"] + pub MANUAL_RANGE_PATTERNS, + complexity, + "manually writing range patterns using a combined OR pattern (`|`)" +} +declare_lint_pass!(ManualRangePatterns => [MANUAL_RANGE_PATTERNS]); + +fn expr_as_i128(expr: &Expr<'_>) -> Option { + if let ExprKind::Unary(UnOp::Neg, expr) = expr.kind { + expr_as_i128(expr).map(|num| -num) + } else if let ExprKind::Lit(lit) = expr.kind + && let LitKind::Int(num, _) = lit.node + { + // Intentionally not handling numbers greater than i128::MAX (for u128 literals) for now. + num.try_into().ok() + } else { + None + } +} + +impl LateLintPass<'_> for ManualRangePatterns { + fn check_pat(&mut self, cx: &LateContext<'_>, pat: &'_ rustc_hir::Pat<'_>) { + if in_external_macro(cx.sess(), pat.span) { + return; + } + + // a pattern like 1 | 2 seems fine, lint if there are at least 3 alternatives + if let PatKind::Or(pats) = pat.kind + && pats.len() >= 3 + { + let mut min = i128::MAX; + let mut max = i128::MIN; + let mut numbers_found = FxHashSet::default(); + let mut ranges_found = Vec::new(); + + for pat in pats { + if let PatKind::Lit(lit) = pat.kind + && let Some(num) = expr_as_i128(lit) + { + numbers_found.insert(num); + + min = min.min(num); + max = max.max(num); + } else if let PatKind::Range(Some(left), Some(right), end) = pat.kind + && let Some(left) = expr_as_i128(left) + && let Some(right) = expr_as_i128(right) + && right >= left + { + min = min.min(left); + max = max.max(right); + ranges_found.push(left..=match end { + RangeEnd::Included => right, + RangeEnd::Excluded => right - 1, + }); + } else { + return; + } + } + + let contains_whole_range = 'contains: { + let mut num = min; + while num <= max { + if numbers_found.contains(&num) { + num += 1; + } + // Given a list of (potentially overlapping) ranges like: + // 1..=5, 3..=7, 6..=10 + // We want to find the range with the highest end that still contains the current number + else if let Some(range) = ranges_found + .iter() + .filter(|range| range.contains(&num)) + .max_by_key(|range| range.end()) + { + num = range.end() + 1; + } else { + break 'contains false; + } + } + break 'contains true; + }; + + if contains_whole_range { + span_lint_and_sugg( + cx, + MANUAL_RANGE_PATTERNS, + pat.span, + "this OR pattern can be rewritten using a range", + "try", + format!("{min}..={max}"), + Applicability::MachineApplicable, + ); + } + } + } +} diff --git a/clippy_lints/src/manual_rem_euclid.rs b/clippy_lints/src/manual_rem_euclid.rs index aafee92713fe..0e89ca132ef9 100644 --- a/clippy_lints/src/manual_rem_euclid.rs +++ b/clippy_lints/src/manual_rem_euclid.rs @@ -119,7 +119,7 @@ fn check_for_either_unsigned_int_constant<'a>( } fn check_for_unsigned_int_constant<'a>(cx: &'a LateContext<'_>, expr: &'a Expr<'_>) -> Option { - let Some(int_const) = constant_full_int(cx, cx.typeck_results(), expr) else { return None }; + let int_const = constant_full_int(cx, cx.typeck_results(), expr)?; match int_const { FullInt::S(s) => s.try_into().ok(), FullInt::U(u) => Some(u), diff --git a/clippy_lints/src/manual_retain.rs b/clippy_lints/src/manual_retain.rs index 72cdb9c17361..5259066eb713 100644 --- a/clippy_lints/src/manual_retain.rs +++ b/clippy_lints/src/manual_retain.rs @@ -46,7 +46,7 @@ declare_clippy_lint! { #[clippy::version = "1.64.0"] pub MANUAL_RETAIN, perf, - "`retain()` is simpler and the same functionalitys" + "`retain()` is simpler and the same functionalities" } pub struct ManualRetain { diff --git a/clippy_lints/src/manual_slice_size_calculation.rs b/clippy_lints/src/manual_slice_size_calculation.rs index 92ee79453a3b..91abcd87dec8 100644 --- a/clippy_lints/src/manual_slice_size_calculation.rs +++ b/clippy_lints/src/manual_slice_size_calculation.rs @@ -1,5 +1,53 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_with_context; +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::{expr_or_init, in_constant, std_or_core}; +======= +use clippy_utils::{expr_or_init, in_constant}; +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= +use clippy_utils::{expr_or_init, in_constant, std_or_core}; +>>>>>>> a2580db64 (Use `clippy_utils::std_or_core` in manual slice size calculation lint) +use rustc_errors::Applicability; +======= use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::{expr_or_init, in_constant}; +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +======= +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_with_context; +<<<<<<< HEAD +use clippy_utils::{expr_or_init, in_constant, std_or_core}; +======= +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::{expr_or_init, in_constant, std_or_core}; +======= +use clippy_utils::{expr_or_init, in_constant}; +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= +use clippy_utils::{expr_or_init, in_constant, std_or_core}; +>>>>>>> a2580db64 (Use `clippy_utils::std_or_core` in manual slice size calculation lint) +>>>>>>> e4f5d83fa (Fixed formatting.) +use rustc_errors::Applicability; +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +======= +// run-rustfix +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_with_context; +use clippy_utils::{expr_or_init, in_constant, std_or_core}; +use rustc_errors::Applicability; +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; @@ -38,19 +86,186 @@ declare_lint_pass!(ManualSliceSizeCalculation => [MANUAL_SLICE_SIZE_CALCULATION] impl<'tcx> LateLintPass<'tcx> for ManualSliceSizeCalculation { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) + // Does not apply inside const because size_of_val is not cost in stable. + if !in_constant(cx, expr.hir_id) + && let ExprKind::Binary(ref op, left, right) = expr.kind + && BinOpKind::Mul == op.node +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + && !expr.span.from_expansion() +======= +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= + && !expr.span.from_expansion() +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +======= +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= + && !expr.span.from_expansion() +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) + && let Some(receiver) = simplify(cx, left, right) + { + let ctxt = expr.span.ctxt(); + let mut app = Applicability::MachineApplicable; + let val_name = snippet_with_context(cx, receiver.span, ctxt, "slice", &mut app).0; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + let Some(sugg) = std_or_core(cx) else { return }; +======= +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= + let Some(sugg) = std_or_core(cx) else { return }; +>>>>>>> a2580db64 (Use `clippy_utils::std_or_core` in manual slice size calculation lint) +======= + let Some(sugg) = std_or_core(cx) else { return }; +>>>>>>> a2580db64 (Use `clippy_utils::std_or_core` in manual slice size calculation lint) + + span_lint_and_sugg( + cx, + MANUAL_SLICE_SIZE_CALCULATION, +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + expr.span, + "manual slice size calculation", +<<<<<<< HEAD +======= + expr.span, + "manual slice size calculation", +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +======= + expr.span, + "manual slice size calculation", +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) + "try", + format!("{sugg}::mem::size_of_val({val_name})"), + app, + ); +<<<<<<< HEAD +<<<<<<< HEAD +======= + None, + "consider using std::mem::size_of_val instead"); +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) +======= + expr.span, + "manual slice size calculation", + "try", + format!("{sugg}::mem::size_of_val({val_name})"), + Applicability::MachineApplicable, + ); +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +======= // Does not apply inside const because size_of_value is not cost in stable. +======= + // Does not apply inside const because size_of_val is not cost in stable. +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) if !in_constant(cx, expr.hir_id) && let ExprKind::Binary(ref op, left, right) = expr.kind && BinOpKind::Mul == op.node - && let Some(_receiver) = simplify(cx, left, right) +======= +>>>>>>> 4da6e7e06 (rebase attempt) + && !expr.span.from_expansion() +======= +<<<<<<< HEAD +<<<<<<< HEAD + && !expr.span.from_expansion() +======= +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= + && !expr.span.from_expansion() +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +>>>>>>> e4f5d83fa (Fixed formatting.) + && let Some(receiver) = simplify(cx, left, right) { - span_lint_and_help( + let ctxt = expr.span.ctxt(); + let mut app = Applicability::MachineApplicable; + let val_name = snippet_with_context(cx, receiver.span, ctxt, "slice", &mut app).0; +<<<<<<< HEAD + let Some(sugg) = std_or_core(cx) else { return }; +======= +<<<<<<< HEAD +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= +<<<<<<< HEAD +<<<<<<< HEAD + let Some(sugg) = std_or_core(cx) else { return }; +======= +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= + let Some(sugg) = std_or_core(cx) else { return }; +>>>>>>> a2580db64 (Use `clippy_utils::std_or_core` in manual slice size calculation lint) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + + span_lint_and_sugg( cx, MANUAL_SLICE_SIZE_CALCULATION, +<<<<<<< HEAD +<<<<<<< HEAD expr.span, "manual slice size calculation", +<<<<<<< HEAD None, +<<<<<<< HEAD "consider using std::mem::size_of_value instead"); +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +======= +<<<<<<< HEAD + expr.span, + "manual slice size calculation", +<<<<<<< HEAD +======= +<<<<<<< HEAD +======= + expr.span, + "manual slice size calculation", +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + "try", + format!("{sugg}::mem::size_of_val({val_name})"), + app, + ); +<<<<<<< HEAD +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +======= +<<<<<<< HEAD +======= +<<<<<<< HEAD +======= + None, +>>>>>>> 4da6e7e06 (rebase attempt) + "consider using std::mem::size_of_val instead"); +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) +======= + expr.span, + "manual slice size calculation", + "try", + format!("{sugg}::mem::size_of_val({val_name})"), + Applicability::MachineApplicable, + ); +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +<<<<<<< HEAD +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) } } } @@ -71,9 +286,27 @@ fn simplify_half<'tcx>( expr1: &'tcx Expr<'tcx>, expr2: &'tcx Expr<'tcx>, ) -> Option<&'tcx Expr<'tcx>> { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if !expr1.span.from_expansion() + // expr1 is `[T1].len()`? + && let ExprKind::MethodCall(method_path, receiver, _, _) = expr1.kind +======= if // expr1 is `[T1].len()`? let ExprKind::MethodCall(method_path, receiver, _, _) = expr1.kind +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + if !expr1.span.from_expansion() + // expr1 is `[T1].len()`? + && let ExprKind::MethodCall(method_path, receiver, _, _) = expr1.kind +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + if !expr1.span.from_expansion() + // expr1 is `[T1].len()`? + && let ExprKind::MethodCall(method_path, receiver, _, _) = expr1.kind +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) && method_path.ident.name == sym::len && let receiver_ty = cx.typeck_results().expr_ty(receiver) && let ty::Slice(ty1) = receiver_ty.peel_refs().kind() diff --git a/clippy_lints/src/manual_strip.rs b/clippy_lints/src/manual_strip.rs index c795c1d9a16c..2b9def1a6884 100644 --- a/clippy_lints/src/manual_strip.rs +++ b/clippy_lints/src/manual_strip.rs @@ -8,8 +8,7 @@ use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_hir::def::Res; use rustc_hir::intravisit::{walk_expr, Visitor}; -use rustc_hir::BinOpKind; -use rustc_hir::{BorrowKind, Expr, ExprKind}; +use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_tool_lint, impl_lint_pass}; @@ -144,7 +143,7 @@ fn len_arg<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx E // Returns the length of the `expr` if it's a constant string or char. fn constant_length(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { - let (value, _) = constant(cx, cx.typeck_results(), expr)?; + let value = constant(cx, cx.typeck_results(), expr)?; match value { Constant::Str(value) => Some(value.len() as u128), Constant::Char(value) => Some(value.len_utf8() as u128), @@ -159,7 +158,7 @@ fn eq_pattern_length<'tcx>(cx: &LateContext<'tcx>, pattern: &Expr<'_>, expr: &'t .. }) = expr.kind { - constant_length(cx, pattern).map_or(false, |length| length == n) + constant_length(cx, pattern).map_or(false, |length| length == *n) } else { len_arg(cx, expr).map_or(false, |arg| eq_expr_value(cx, pattern, arg)) } diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index edcab6968cbe..1b3a47e4acd9 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -226,7 +226,7 @@ fn lint_map_unit_fn( ); span_lint_and_then(cx, lint, expr.span, &msg, |diag| { - diag.span_suggestion(stmt.span, "try this", suggestion, applicability); + diag.span_suggestion(stmt.span, "try", suggestion, applicability); }); } else if let Some((binding, closure_expr)) = unit_closure(cx, fn_arg) { let msg = suggestion_msg("closure", map_type); @@ -241,7 +241,7 @@ fn lint_map_unit_fn( snippet_with_applicability(cx, var_arg.span, "_", &mut applicability), snippet_with_context(cx, reduced_expr_span, var_arg.span.ctxt(), "_", &mut applicability).0, ); - diag.span_suggestion(stmt.span, "try this", suggestion, applicability); + diag.span_suggestion(stmt.span, "try", suggestion, applicability); } else { let suggestion = format!( "if let {0}({1}) = {2} {{ ... }}", @@ -249,7 +249,7 @@ fn lint_map_unit_fn( snippet(cx, binding.pat.span, "_"), snippet(cx, var_arg.span, "_"), ); - diag.span_suggestion(stmt.span, "try this", suggestion, Applicability::HasPlaceholders); + diag.span_suggestion(stmt.span, "try", suggestion, Applicability::HasPlaceholders); } }); } diff --git a/clippy_lints/src/match_result_ok.rs b/clippy_lints/src/match_result_ok.rs index 6ec9784038c3..841c020f2d3d 100644 --- a/clippy_lints/src/match_result_ok.rs +++ b/clippy_lints/src/match_result_ok.rs @@ -1,8 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::higher; -use clippy_utils::is_res_lang_ctor; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::{higher, is_res_lang_ctor}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, LangItem, PatKind}; diff --git a/clippy_lints/src/matches/infallible_destructuring_match.rs b/clippy_lints/src/matches/infallible_destructuring_match.rs index d18c92caba2a..3329f93b73c4 100644 --- a/clippy_lints/src/matches/infallible_destructuring_match.rs +++ b/clippy_lints/src/matches/infallible_destructuring_match.rs @@ -28,7 +28,7 @@ pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool { local.span, "you seem to be trying to use `match` to destructure a single infallible pattern. \ Consider using `let`", - "try this", + "try", format!( "let {}({}{}) = {};", snippet_with_applicability(cx, variant_name.span, "..", &mut applicability), diff --git a/clippy_lints/src/matches/manual_filter.rs b/clippy_lints/src/matches/manual_filter.rs index f6bf0e7aa1ad..e0181a4757c0 100644 --- a/clippy_lints/src/matches/manual_filter.rs +++ b/clippy_lints/src/matches/manual_filter.rs @@ -143,7 +143,7 @@ fn check<'tcx>( MANUAL_FILTER, expr.span, "manual implementation of `Option::filter`", - "try this", + "try", if sugg_info.needs_brackets { format!( "{{ {}{}.filter({body_str}) }}", diff --git a/clippy_lints/src/matches/manual_map.rs b/clippy_lints/src/matches/manual_map.rs index aaba239677ff..ed3d8b09fdcd 100644 --- a/clippy_lints/src/matches/manual_map.rs +++ b/clippy_lints/src/matches/manual_map.rs @@ -58,7 +58,7 @@ fn check<'tcx>( MANUAL_MAP, expr.span, "manual implementation of `Option::map`", - "try this", + "try", if sugg_info.needs_brackets { format!( "{{ {}{}.map({}) }}", diff --git a/clippy_lints/src/matches/manual_utils.rs b/clippy_lints/src/matches/manual_utils.rs index 5b7644a53832..6b611f567ae2 100644 --- a/clippy_lints/src/matches/manual_utils.rs +++ b/clippy_lints/src/matches/manual_utils.rs @@ -1,14 +1,17 @@ -use crate::{map_unit_fn::OPTION_MAP_UNIT_FN, matches::MATCH_AS_REF}; +use crate::map_unit_fn::OPTION_MAP_UNIT_FN; +use crate::matches::MATCH_AS_REF; use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; +use clippy_utils::sugg::Sugg; use clippy_utils::ty::{is_copy, is_type_diagnostic_item, peel_mid_ty_refs_is_mutable, type_is_unsafe_function}; use clippy_utils::{ can_move_expr_to_closure, is_else_clause, is_lint_allowed, is_res_lang_ctor, path_res, path_to_local_id, - peel_blocks, peel_hir_expr_refs, peel_hir_expr_while, sugg::Sugg, CaptureKind, + peel_blocks, peel_hir_expr_refs, peel_hir_expr_while, CaptureKind, }; use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::Applicability; +use rustc_hir::def::Res; use rustc_hir::LangItem::{OptionNone, OptionSome}; -use rustc_hir::{def::Res, BindingAnnotation, Expr, ExprKind, HirId, Mutability, Pat, PatKind, Path, QPath}; +use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, Mutability, Pat, PatKind, Path, QPath}; use rustc_lint::LateContext; use rustc_span::{sym, SyntaxContext}; diff --git a/clippy_lints/src/matches/match_as_ref.rs b/clippy_lints/src/matches/match_as_ref.rs index 2818f030b7a6..a6392b7aaec2 100644 --- a/clippy_lints/src/matches/match_as_ref.rs +++ b/clippy_lints/src/matches/match_as_ref.rs @@ -46,7 +46,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: MATCH_AS_REF, expr.span, &format!("use `{suggestion}()` instead"), - "try this", + "try", format!( "{}.{suggestion}(){cast}", snippet_with_applicability(cx, ex.span, "_", &mut applicability), diff --git a/clippy_lints/src/matches/match_like_matches.rs b/clippy_lints/src/matches/match_like_matches.rs index 107fad32393c..845de1762cdd 100644 --- a/clippy_lints/src/matches/match_like_matches.rs +++ b/clippy_lints/src/matches/match_like_matches.rs @@ -1,10 +1,10 @@ +use super::REDUNDANT_PATTERN_MATCHING; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::is_wild; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::span_contains_comment; +use clippy_utils::{is_lint_allowed, is_wild, span_contains_comment}; use rustc_ast::{Attribute, LitKind}; use rustc_errors::Applicability; -use rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Guard, Pat}; +use rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Guard, Pat, PatKind, QPath}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty; use rustc_span::source_map::Spanned; @@ -99,6 +99,14 @@ where } } + for arm in iter_without_last.clone() { + if let Some(pat) = arm.1 { + if !is_lint_allowed(cx, REDUNDANT_PATTERN_MATCHING, pat.hir_id) && is_some(pat.kind) { + return false; + } + } + } + // The suggestion may be incorrect, because some arms can have `cfg` attributes // evaluated into `false` and so such arms will be stripped before. let mut applicability = Applicability::MaybeIncorrect; @@ -129,7 +137,7 @@ where MATCH_LIKE_MATCHES_MACRO, expr.span, &format!("{} expression looks like `matches!` macro", if is_if_let { "if let .. else" } else { "match" }), - "try this", + "try", format!( "{}matches!({}, {pat_and_guard})", if b0 { "" } else { "!" }, @@ -162,7 +170,7 @@ fn find_bool_lit(ex: &ExprKind<'_>) -> Option { node: LitKind::Bool(b), .. }) = exp.kind { - Some(b) + Some(*b) } else { None } @@ -170,3 +178,40 @@ fn find_bool_lit(ex: &ExprKind<'_>) -> Option { _ => None, } } + +fn is_some(path_kind: PatKind<'_>) -> bool { + match path_kind { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + PatKind::TupleStruct(QPath::Resolved(_, path), [first, ..], _) if is_wild(first) => { + let name = path.segments[0].ident; + name.name == rustc_span::sym::Some +======= + PatKind::TupleStruct(ref path_left, patterns, _) if is_wild(&patterns[0]) => match path_left { + QPath::Resolved(_, path) => { + let name = path.segments[0].ident; + if name.as_str() == "Some" { + return true; + } + return false; + }, + _ => false, +>>>>>>> 9e535f628 (fix conflict with matches macro) +======= + PatKind::TupleStruct(QPath::Resolved(_, path), patterns, _) if is_wild(&patterns[0]) => { + let name = path.segments[0].ident; + if name.name == rustc_span::sym::Some { + return true; + } + false +>>>>>>> 630f31ce5 (fix conflict with matches macro) +======= + PatKind::TupleStruct(QPath::Resolved(_, path), [first, ..], _) if is_wild(first) => { + let name = path.segments[0].ident; + name.name == rustc_span::sym::Some +>>>>>>> 342ce3da0 (fix reviewer comments) + }, + _ => false, + } +} diff --git a/clippy_lints/src/matches/match_on_vec_items.rs b/clippy_lints/src/matches/match_on_vec_items.rs index 2917f85c45f5..89dcac4d8494 100644 --- a/clippy_lints/src/matches/match_on_vec_items.rs +++ b/clippy_lints/src/matches/match_on_vec_items.rs @@ -22,7 +22,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>) { MATCH_ON_VEC_ITEMS, scrutinee.span, "indexing into a vector may panic", - "try this", + "try", format!( "{}.get({})", snippet(cx, vec.span, ".."), diff --git a/clippy_lints/src/matches/match_same_arms.rs b/clippy_lints/src/matches/match_same_arms.rs index 158e6caa4de5..0553b41328e5 100644 --- a/clippy_lints/src/matches/match_same_arms.rs +++ b/clippy_lints/src/matches/match_same_arms.rs @@ -1,14 +1,14 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; -use clippy_utils::{path_to_local, search_same, SpanlessEq, SpanlessHash}; +use clippy_utils::{is_lint_allowed, path_to_local, search_same, SpanlessEq, SpanlessHash}; use core::cmp::Ordering; -use core::iter; -use core::slice; +use core::{iter, slice}; use rustc_arena::DroplessArena; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatKind, RangeEnd}; +use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::Symbol; @@ -103,17 +103,21 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) { let indexed_arms: Vec<(usize, &Arm<'_>)> = arms.iter().enumerate().collect(); for (&(i, arm1), &(j, arm2)) in search_same(&indexed_arms, hash, eq) { if matches!(arm2.pat.kind, PatKind::Wild) { - span_lint_and_then( - cx, - MATCH_SAME_ARMS, - arm1.span, - "this match arm has an identical body to the `_` wildcard arm", - |diag| { - diag.span_suggestion(arm1.span, "try removing the arm", "", Applicability::MaybeIncorrect) - .help("or try changing either arm body") - .span_note(arm2.span, "`_` wildcard arm here"); - }, - ); + if !cx.tcx.features().non_exhaustive_omitted_patterns_lint + || is_lint_allowed(cx, NON_EXHAUSTIVE_OMITTED_PATTERNS, arm2.hir_id) + { + span_lint_and_then( + cx, + MATCH_SAME_ARMS, + arm1.span, + "this match arm has an identical body to the `_` wildcard arm", + |diag| { + diag.span_suggestion(arm1.span, "try removing the arm", "", Applicability::MaybeIncorrect) + .help("or try changing either arm body") + .span_note(arm2.span, "`_` wildcard arm here"); + }, + ); + } } else { let back_block = backwards_blocking_idxs[j]; let (keep_arm, move_arm) = if back_block < i || (back_block == 0 && forwards_blocking_idxs[i] <= j) { @@ -282,7 +286,7 @@ impl<'a> NormalizedPat<'a> { // TODO: Handle negative integers. They're currently treated as a wild match. ExprKind::Lit(lit) => match lit.node { LitKind::Str(sym, _) => Self::LitStr(sym), - LitKind::ByteStr(ref bytes, _) => Self::LitBytes(bytes), + LitKind::ByteStr(ref bytes, _) | LitKind::CStr(ref bytes, _) => Self::LitBytes(bytes), LitKind::Byte(val) => Self::LitInt(val.into()), LitKind::Char(val) => Self::LitInt(val.into()), LitKind::Int(val, _) => Self::LitInt(val), diff --git a/clippy_lints/src/matches/match_wild_enum.rs b/clippy_lints/src/matches/match_wild_enum.rs index 3126b590180e..8d22ceb47f85 100644 --- a/clippy_lints/src/matches/match_wild_enum.rs +++ b/clippy_lints/src/matches/match_wild_enum.rs @@ -143,7 +143,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { MATCH_WILDCARD_FOR_SINGLE_VARIANTS, wildcard_span, "wildcard matches only a single variant and will also match any future added variants", - "try this", + "try", format_suggestion(x), Applicability::MaybeIncorrect, ), @@ -161,7 +161,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { WILDCARD_ENUM_MATCH_ARM, wildcard_span, message, - "try this", + "try", suggestions.join(" | "), Applicability::MaybeIncorrect, ); diff --git a/clippy_lints/src/matches/match_wild_err_arm.rs b/clippy_lints/src/matches/match_wild_err_arm.rs index 42f1e2629d41..de911f7a0280 100644 --- a/clippy_lints/src/matches/match_wild_err_arm.rs +++ b/clippy_lints/src/matches/match_wild_err_arm.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_note; use clippy_utils::macros::{is_panic, root_macro_call}; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::is_local_used; -use clippy_utils::{is_wild, peel_blocks_with_stmt}; +use clippy_utils::{in_constant, is_wild, peel_blocks_with_stmt}; use rustc_hir::{Arm, Expr, PatKind}; use rustc_lint::LateContext; use rustc_span::symbol::{kw, sym}; @@ -10,6 +10,11 @@ use rustc_span::symbol::{kw, sym}; use super::MATCH_WILD_ERR_ARM; pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<'tcx>]) { + // `unwrap`/`expect` is not (yet) const, so we want to allow this in const contexts for now + if in_constant(cx, ex.hir_id) { + return; + } + let ex_ty = cx.typeck_results().expr_ty(ex).peel_refs(); if is_type_diagnostic_item(cx, ex_ty, sym::Result) { for arm in arms { @@ -20,7 +25,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<' let mut ident_bind_name = kw::Underscore; if !matching_wild { // Looking for unused bindings (i.e.: `_e`) - for pat in inner.iter() { + for pat in inner { if let PatKind::Binding(_, id, ident, None) = pat.kind { if ident.as_str().starts_with('_') && !is_local_used(cx, arm.body, id) { ident_bind_name = ident.name; diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs index 87b63eead253..93368588c3ae 100644 --- a/clippy_lints/src/matches/mod.rs +++ b/clippy_lints/src/matches/mod.rs @@ -25,9 +25,17 @@ mod wild_in_or_pats; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{snippet_opt, walk_span_to_context}; -use clippy_utils::{higher, in_constant, is_span_match}; +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, tokenize_with_text}; +======= +use clippy_utils::{higher, in_constant, is_span_match, tokenize_with_text}; +>>>>>>> 0b3c2ed81 (Search for inactive `cfg` attributes and empty macro expansion through) +======= +use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, tokenize_with_text}; +>>>>>>> 0b507c6f0 (redundant pattern matches! result) use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat}; -use rustc_lexer::{tokenize, TokenKind}; +use rustc_lexer::TokenKind; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_tool_lint, impl_lint_pass}; @@ -38,6 +46,11 @@ declare_clippy_lint! { /// Checks for matches with a single arm where an `if let` /// will usually suffice. /// + /// This intentionally does not lint if there are comments + /// inside of the other arm, so as to allow the user to document + /// why having another explicit pattern with an empty body is necessary, + /// or because the comments need to be preserved for other reasons. + /// /// ### Why is this bad? /// Just readability – `if let` nests less than a `match`. /// @@ -559,6 +572,9 @@ declare_clippy_lint! { /// ### What it does /// Checks for `match` with identical arm bodies. /// + /// Note: Does not lint on wildcards if the `non_exhaustive_omitted_patterns_lint` feature is + /// enabled and disallowed. + /// /// ### Why is this bad? /// This is probably a copy & paste error. If arm bodies /// are the same on purpose, you can factor them @@ -777,7 +793,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Check for temporaries returned from function calls in a match scrutinee that have the + /// Checks for temporaries returned from function calls in a match scrutinee that have the /// `clippy::has_significant_drop` attribute. /// /// ### Why is this bad? @@ -974,12 +990,16 @@ impl_lint_pass!(Matches => [ impl<'tcx> LateLintPass<'tcx> for Matches { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if in_external_macro(cx.sess(), expr.span) { + if is_direct_expn_of(expr.span, "matches").is_none() && in_external_macro(cx.sess(), expr.span) { return; } let from_expansion = expr.span.from_expansion(); if let ExprKind::Match(ex, arms, source) = expr.kind { + if is_direct_expn_of(expr.span, "matches").is_some() { + redundant_pattern_match::check_match(cx, expr, ex, arms); + } + if source == MatchSource::Normal && !is_span_match(cx, expr.span) { return; } @@ -1147,12 +1167,7 @@ fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool { // Assume true. This would require either an invalid span, or one which crosses file boundaries. return true; }; - let mut pos = 0usize; - let mut iter = tokenize(&snip).map(|t| { - let start = pos; - pos += t.len as usize; - (t.kind, start..pos) - }); + let mut iter = tokenize_with_text(&snip); // Search for the token sequence [`#`, `[`, `cfg`] while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) { @@ -1163,7 +1178,7 @@ fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool { ) }); if matches!(iter.next(), Some((TokenKind::OpenBracket, _))) - && matches!(iter.next(), Some((TokenKind::Ident, range)) if &snip[range.clone()] == "cfg") + && matches!(iter.next(), Some((TokenKind::Ident, "cfg"))) { return true; } diff --git a/clippy_lints/src/matches/overlapping_arms.rs b/clippy_lints/src/matches/overlapping_arms.rs index ae69ca8a3393..8be3c178a291 100644 --- a/clippy_lints/src/matches/overlapping_arms.rs +++ b/clippy_lints/src/matches/overlapping_arms.rs @@ -34,25 +34,25 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>) if let Arm { pat, guard: None, .. } = *arm { if let PatKind::Range(ref lhs, ref rhs, range_end) = pat.kind { let lhs_const = match lhs { - Some(lhs) => constant(cx, cx.typeck_results(), lhs)?.0, + Some(lhs) => constant(cx, cx.typeck_results(), lhs)?, None => { let min_val_const = ty.numeric_min_val(cx.tcx)?; let min_constant = mir::ConstantKind::from_value( cx.tcx.valtree_to_const_val((ty, min_val_const.to_valtree())), ty, ); - miri_to_const(cx.tcx, min_constant)? + miri_to_const(cx, min_constant)? }, }; let rhs_const = match rhs { - Some(rhs) => constant(cx, cx.typeck_results(), rhs)?.0, + Some(rhs) => constant(cx, cx.typeck_results(), rhs)?, None => { let max_val_const = ty.numeric_max_val(cx.tcx)?; let max_constant = mir::ConstantKind::from_value( cx.tcx.valtree_to_const_val((ty, max_val_const.to_valtree())), ty, ); - miri_to_const(cx.tcx, max_constant)? + miri_to_const(cx, max_constant)? }, }; let lhs_val = lhs_const.int_value(cx, ty)?; diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index 7b609ff3df8f..7d59122f1f66 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -1,10 +1,10 @@ use super::REDUNDANT_PATTERN_MATCHING; -use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::source::{snippet, walk_span_to_context}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{is_type_diagnostic_item, needs_ordered_drop}; use clippy_utils::visitors::any_temporaries_need_ordered_drop; -use clippy_utils::{higher, is_trait_method}; +use clippy_utils::{higher, is_expn_of, is_trait_method}; use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; @@ -12,7 +12,8 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::LangItem::{self, OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk}; use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatKind, QPath, UnOp}; use rustc_lint::LateContext; -use rustc_middle::ty::{self, subst::GenericArgKind, Ty}; +use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::{self, Ty}; use rustc_span::{sym, Symbol}; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { @@ -63,8 +64,11 @@ fn find_sugg_for_if_let<'tcx>( // Determine which function should be used, and the type contained by the corresponding // variant. let (good_method, inner_ty) = match check_pat.kind { - PatKind::TupleStruct(ref qpath, [sub_pat], _) => { - if let PatKind::Wild = sub_pat.kind { + PatKind::TupleStruct(ref qpath, args, rest) => { + let is_wildcard = matches!(args.first().map(|p| &p.kind), Some(PatKind::Wild)); + let is_rest = matches!((args, rest.as_opt_usize()), ([], Some(_))); + + if is_wildcard || is_rest { let res = cx.typeck_results().qpath_res(qpath, check_pat.hir_id); let Some(id) = res.opt_def_id().map(|ctor_id| cx.tcx.parent(ctor_id)) else { return }; let lang_items = cx.tcx.lang_items(); @@ -172,7 +176,7 @@ fn find_sugg_for_if_let<'tcx>( .maybe_par() .to_string(); - diag.span_suggestion(span, "try this", format!("{keyword} {sugg}.{good_method}"), app); + diag.span_suggestion(span, "try", format!("{keyword} {sugg}.{good_method}"), app); if needs_drop { diag.note("this will change drop order of the result, as well as all temporaries"); @@ -185,7 +189,13 @@ fn find_sugg_for_if_let<'tcx>( pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) { if arms.len() == 2 { let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if let Some(good_method) = found_good_method(cx, arms, node_pair) { + let span = is_expn_of(expr.span, "matches").unwrap_or(expr.span.to(op.span)); +======= let found_good_method = match node_pair { ( PatKind::TupleStruct(ref path_left, patterns_left, _), @@ -249,33 +259,262 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op None } }, + (PatKind::TupleStruct(ref path_left, patterns, _), PatKind::Wild) if patterns.len() == 1 => { + if let PatKind::Wild = patterns[0].kind { + let ident = match path_left { + QPath::Resolved(_, path) => { + let name = path.segments[0].ident; + Some(name) + }, + _ => None, + }; + if let Some(name) = ident { + match name.as_str() { + "Ok" => find_good_method_for_matches_macro( + cx, + arms, + path_left, + Item::Lang(ResultOk), + "is_ok()", + "is_err()", + ), + "Some" => find_good_method_for_matches_macro( + cx, + arms, + path_left, + Item::Lang(OptionSome), + "is_some()", + "is_none()", + ), + _ => None, + } + } else { + None + } + } else { + None + } + }, + (PatKind::Path(ref path_left), PatKind::Wild) => { + let ident = match path_left { + QPath::Resolved(_, path) => { + let name = path.segments[0].ident; + Some(name) + }, + _ => None, + }; + + if let Some(name) = ident { + match name.as_str() { + "None" => find_good_method_for_matches_macro( + cx, + arms, + path_left, + Item::Lang(OptionNone), + "is_none()", + "is_some()", + ), + _ => None, + } + } else { + None + } + }, _ => None, }; +======= + let found_good_method = found_good_method(cx, arms, node_pair); +>>>>>>> 630f31ce5 (fix conflict with matches macro) +======= +>>>>>>> 342ce3da0 (fix reviewer comments) - if let Some(good_method) = found_good_method { + if let Some(good_method) = found_good_method(cx, arms, node_pair) { +<<<<<<< HEAD let span = expr.span.to(op.span); +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + let span = is_expn_of(expr.span, "matches").unwrap_or(expr.span.to(op.span)); +>>>>>>> 0b507c6f0 (redundant pattern matches! result) let result_expr = match &op.kind { ExprKind::AddrOf(_, _, borrowed) => borrowed, _ => op, }; - span_lint_and_then( + span_lint_and_sugg( cx, REDUNDANT_PATTERN_MATCHING, - expr.span, + span, &format!("redundant pattern matching, consider using `{good_method}`"), - |diag| { - diag.span_suggestion( - span, - "try this", - format!("{}.{good_method}", snippet(cx, result_expr.span, "_")), - Applicability::MaybeIncorrect, // snippet - ); - }, + "try", + format!("{}.{good_method}", snippet(cx, result_expr.span, "_")), + Applicability::MachineApplicable, ); } } } +fn found_good_method<'a>( + cx: &LateContext<'_>, + arms: &[Arm<'_>], + node: (&PatKind<'_>, &PatKind<'_>), +) -> Option<&'a str> { + match node { + ( + PatKind::TupleStruct(ref path_left, patterns_left, _), + PatKind::TupleStruct(ref path_right, patterns_right, _), + ) if patterns_left.len() == 1 && patterns_right.len() == 1 => { + if let (PatKind::Wild, PatKind::Wild) = (&patterns_left[0].kind, &patterns_right[0].kind) { + find_good_method_for_match( + cx, + arms, + path_left, + path_right, + Item::Lang(ResultOk), + Item::Lang(ResultErr), + "is_ok()", + "is_err()", + ) + .or_else(|| { + find_good_method_for_match( + cx, + arms, + path_left, + path_right, + Item::Diag(sym::IpAddr, sym!(V4)), + Item::Diag(sym::IpAddr, sym!(V6)), + "is_ipv4()", + "is_ipv6()", + ) + }) + } else { + None + } + }, + (PatKind::TupleStruct(ref path_left, patterns, _), PatKind::Path(ref path_right)) + | (PatKind::Path(ref path_left), PatKind::TupleStruct(ref path_right, patterns, _)) + if patterns.len() == 1 => + { + if let PatKind::Wild = patterns[0].kind { + find_good_method_for_match( + cx, + arms, + path_left, + path_right, + Item::Lang(OptionSome), + Item::Lang(OptionNone), + "is_some()", + "is_none()", + ) + .or_else(|| { + find_good_method_for_match( + cx, + arms, + path_left, + path_right, + Item::Lang(PollReady), + Item::Lang(PollPending), + "is_ready()", + "is_pending()", + ) + }) + } else { + None + } + }, + (PatKind::TupleStruct(ref path_left, patterns, _), PatKind::Wild) if patterns.len() == 1 => { + if let PatKind::Wild = patterns[0].kind { + get_good_method(cx, arms, path_left) + } else { + None + } + }, +<<<<<<< HEAD +<<<<<<< HEAD + (PatKind::Path(ref path_left), PatKind::Wild) => get_good_method(cx, arms, path_left), +======= + (PatKind::Path(ref path_left), PatKind::Wild) => { + if let Some(name) = get_ident(path_left) { + match name.as_str() { + "None" => find_good_method_for_matches_macro( + cx, + arms, + path_left, + Item::Lang(OptionNone), + "is_none()", + "is_some()", + ), + _ => None, + } + } else { + None + } + }, +>>>>>>> 630f31ce5 (fix conflict with matches macro) +======= + (PatKind::Path(ref path_left), PatKind::Wild) => get_good_method(cx, arms, path_left), +>>>>>>> fb6bf1ebf (update a func) + _ => None, + } +} + +fn get_ident(path: &QPath<'_>) -> Option { + match path { + QPath::Resolved(_, path) => { + let name = path.segments[0].ident; + Some(name) + }, + _ => None, + } +} + +fn get_good_method<'a>(cx: &LateContext<'_>, arms: &[Arm<'_>], path_left: &QPath<'_>) -> Option<&'a str> { + if let Some(name) = get_ident(path_left) { + return match name.as_str() { + "Ok" => { + find_good_method_for_matches_macro(cx, arms, path_left, Item::Lang(ResultOk), "is_ok()", "is_err()") + }, +<<<<<<< HEAD +<<<<<<< HEAD + "Err" => { + find_good_method_for_matches_macro(cx, arms, path_left, Item::Lang(ResultErr), "is_err()", "is_ok()") + }, +======= +>>>>>>> 630f31ce5 (fix conflict with matches macro) +======= + "Err" => { + find_good_method_for_matches_macro(cx, arms, path_left, Item::Lang(ResultErr), "is_err()", "is_ok()") + }, +>>>>>>> 342ce3da0 (fix reviewer comments) + "Some" => find_good_method_for_matches_macro( + cx, + arms, + path_left, + Item::Lang(OptionSome), + "is_some()", + "is_none()", + ), +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> fb6bf1ebf (update a func) + "None" => find_good_method_for_matches_macro( + cx, + arms, + path_left, + Item::Lang(OptionNone), + "is_none()", + "is_some()", + ), +<<<<<<< HEAD +======= +>>>>>>> 630f31ce5 (fix conflict with matches macro) +======= +>>>>>>> fb6bf1ebf (update a func) + _ => None, + }; + } + None +} + #[derive(Clone, Copy)] enum Item { Lang(LangItem), @@ -286,10 +525,11 @@ fn is_pat_variant(cx: &LateContext<'_>, pat: &Pat<'_>, path: &QPath<'_>, expecte let Some(id) = cx.typeck_results().qpath_res(path, pat.hir_id).opt_def_id() else { return false }; match expected_item { - Item::Lang(expected_lang_item) => { - let expected_id = cx.tcx.lang_items().require(expected_lang_item).unwrap(); - cx.tcx.parent(id) == expected_id - }, + Item::Lang(expected_lang_item) => cx + .tcx + .lang_items() + .get(expected_lang_item) + .map_or(false, |expected_id| cx.tcx.parent(id) == expected_id), Item::Diag(expected_ty, expected_variant) => { let ty = cx.typeck_results().pat_ty(pat); @@ -342,3 +582,36 @@ fn find_good_method_for_match<'a>( _ => None, } } + +<<<<<<< HEAD +<<<<<<< HEAD +======= +#[expect(clippy::too_many_arguments)] +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= +>>>>>>> 630f31ce5 (fix conflict with matches macro) +fn find_good_method_for_matches_macro<'a>( + cx: &LateContext<'_>, + arms: &[Arm<'_>], + path_left: &QPath<'_>, + expected_item_left: Item, + should_be_left: &'a str, + should_be_right: &'a str, +) -> Option<&'a str> { + let first_pat = arms[0].pat; + + let body_node_pair = if is_pat_variant(cx, first_pat, path_left, expected_item_left) { + (&arms[0].body.kind, &arms[1].body.kind) + } else { + return None; + }; + + match body_node_pair { + (ExprKind::Lit(lit_left), ExprKind::Lit(lit_right)) => match (&lit_left.node, &lit_right.node) { + (LitKind::Bool(true), LitKind::Bool(false)) => Some(should_be_left), + (LitKind::Bool(false), LitKind::Bool(true)) => Some(should_be_right), + _ => None, + }, + _ => None, + } +} diff --git a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index 04225beeb704..37528d9f7f20 100644 --- a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -140,7 +140,7 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> { } } - for generic_arg in b.iter() { + for generic_arg in *b { if let GenericArgKind::Type(ty) = generic_arg.unpack() { if self.has_sig_drop_attr(cx, ty) { return true; @@ -329,6 +329,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> { ExprKind::Field(..) | ExprKind::Index(..) | ExprKind::Ret(..) | + ExprKind::Become(..) | ExprKind::Repeat(..) | ExprKind::Yield(..) => walk_expr(self, ex), ExprKind::AddrOf(_, _, _) | @@ -342,6 +343,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> { ExprKind::DropTemps(_) | ExprKind::Err(_) | ExprKind::InlineAsm(_) | + ExprKind::OffsetOf(_, _) | ExprKind::Let(_) | ExprKind::Lit(_) | ExprKind::Loop(_, _, _, _) | diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs index ad47c13896c5..6b05c6bfffdc 100644 --- a/clippy_lints/src/matches/single_match.rs +++ b/clippy_lints/src/matches/single_match.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::{expr_block, snippet}; +use clippy_utils::source::{expr_block, get_source_text, snippet}; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item, peel_mid_ty_refs}; use clippy_utils::{is_lint_allowed, is_unit_expr, is_wild, peel_blocks, peel_hir_pat_refs, peel_n_hir_expr_refs}; use core::cmp::max; @@ -7,10 +7,26 @@ use rustc_errors::Applicability; use rustc_hir::{Arm, BindingAnnotation, Block, Expr, ExprKind, Pat, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; -use rustc_span::sym; +use rustc_span::{sym, Span}; use super::{MATCH_BOOL, SINGLE_MATCH, SINGLE_MATCH_ELSE}; +/// Checks if there are comments contained within a span. +/// This is a very "naive" check, as it just looks for the literal characters // and /* in the +/// source text. This won't be accurate if there are potentially expressions contained within the +/// span, e.g. a string literal `"//"`, but we know that this isn't the case for empty +/// match arms. +fn empty_arm_has_comment(cx: &LateContext<'_>, span: Span) -> bool { + if let Some(ff) = get_source_text(cx, span) + && let Some(text) = ff.as_str() + { + text.as_bytes().windows(2) + .any(|w| w == b"//" || w == b"/*") + } else { + false + } +} + #[rustfmt::skip] pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() { @@ -25,7 +41,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: return; } let els = arms[1].body; - let els = if is_unit_expr(peel_blocks(els)) { + let els = if is_unit_expr(peel_blocks(els)) && !empty_arm_has_comment(cx, els.span) { None } else if let ExprKind::Block(Block { stmts, expr: block_expr, .. }, _) = els.kind { if stmts.len() == 1 && block_expr.is_none() || stmts.is_empty() && block_expr.is_some() { @@ -35,7 +51,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: // block with 2+ statements or 1 expr and 1+ statement Some(els) } else { - // not a block, don't lint + // not a block or an emtpy block w/ comments, don't lint return; }; @@ -120,7 +136,7 @@ fn report_single_pattern( } }; - span_lint_and_sugg(cx, lint, expr.span, msg, "try this", sugg, app); + span_lint_and_sugg(cx, lint, expr.span, msg, "try", sugg, app); } fn check_opt_like<'a>( diff --git a/clippy_lints/src/matches/try_err.rs b/clippy_lints/src/matches/try_err.rs index 704c34c32bf7..99a748489b47 100644 --- a/clippy_lints/src/matches/try_err.rs +++ b/clippy_lints/src/matches/try_err.rs @@ -70,7 +70,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutine TRY_ERR, expr.span, "returning an `Err(_)` with the `?` operator", - "try this", + "try", suggestion, applicability, ); @@ -81,7 +81,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutine /// Finds function return type by examining return expressions in match arms. fn find_return_type<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx ExprKind<'_>) -> Option> { if let ExprKind::Match(_, arms, MatchSource::TryDesugar) = expr { - for arm in arms.iter() { + for arm in *arms { if let ExprKind::Ret(Some(ret)) = arm.body.kind { return Some(cx.typeck_results().expr_ty(ret)); } diff --git a/clippy_lints/src/mem_forget.rs b/clippy_lints/src/mem_forget.rs deleted file mode 100644 index d6c235b5a693..000000000000 --- a/clippy_lints/src/mem_forget.rs +++ /dev/null @@ -1,46 +0,0 @@ -use clippy_utils::diagnostics::span_lint; -use rustc_hir::{Expr, ExprKind}; -use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::sym; - -declare_clippy_lint! { - /// ### What it does - /// Checks for usage of `std::mem::forget(t)` where `t` is - /// `Drop`. - /// - /// ### Why is this bad? - /// `std::mem::forget(t)` prevents `t` from running its - /// destructor, possibly causing leaks. - /// - /// ### Example - /// ```rust - /// # use std::mem; - /// # use std::rc::Rc; - /// mem::forget(Rc::new(55)) - /// ``` - #[clippy::version = "pre 1.29.0"] - pub MEM_FORGET, - restriction, - "`mem::forget` usage on `Drop` types, likely to cause memory leaks" -} - -declare_lint_pass!(MemForget => [MEM_FORGET]); - -impl<'tcx> LateLintPass<'tcx> for MemForget { - fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { - if let ExprKind::Call(path_expr, [ref first_arg, ..]) = e.kind { - if let ExprKind::Path(ref qpath) = path_expr.kind { - if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id() { - if cx.tcx.is_diagnostic_item(sym::mem_forget, def_id) { - let forgot_ty = cx.typeck_results().expr_ty(first_arg); - - if forgot_ty.ty_adt_def().map_or(false, |def| def.has_dtor(cx.tcx)) { - span_lint(cx, MEM_FORGET, e.span, "usage of `mem::forget` on `Drop` type"); - } - } - } - } - } - } -} diff --git a/clippy_lints/src/methods/bind_instead_of_map.rs b/clippy_lints/src/methods/bind_instead_of_map.rs index 00853348840e..3a8cc41748eb 100644 --- a/clippy_lints/src/methods/bind_instead_of_map.rs +++ b/clippy_lints/src/methods/bind_instead_of_map.rs @@ -1,7 +1,8 @@ use super::{contains_return, BIND_INSTEAD_OF_MAP}; use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::peel_blocks; use clippy_utils::source::{snippet, snippet_with_context}; -use clippy_utils::{peel_blocks, visitors::find_all_ret_expressions}; +use clippy_utils::visitors::find_all_ret_expressions; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; @@ -87,7 +88,7 @@ pub(crate) trait BindInsteadOfMap { BIND_INSTEAD_OF_MAP, expr.span, &msg, - "try this", + "try", note, app, ); @@ -124,7 +125,7 @@ pub(crate) trait BindInsteadOfMap { span_lint_and_then(cx, BIND_INSTEAD_OF_MAP, expr.span, &msg, |diag| { multispan_sugg_with_applicability( diag, - "try this", + "try", Applicability::MachineApplicable, std::iter::once((span, Self::GOOD_METHOD_NAME.into())).chain( suggs diff --git a/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs b/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs index 7711aa78b239..41b5cc12d6db 100644 --- a/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs +++ b/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs @@ -1,13 +1,13 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::source::snippet_opt; -use clippy_utils::source::{indent_of, reindent_multiline}; +use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt}; use clippy_utils::ty::is_type_lang_item; use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, LangItem}; use rustc_lint::LateContext; -use rustc_span::{source_map::Spanned, Span}; +use rustc_span::source_map::Spanned; +use rustc_span::Span; use super::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS; diff --git a/clippy_lints/src/methods/chars_cmp.rs b/clippy_lints/src/methods/chars_cmp.rs index 079df2226d1e..0e41f3c21076 100644 --- a/clippy_lints/src/methods/chars_cmp.rs +++ b/clippy_lints/src/methods/chars_cmp.rs @@ -4,8 +4,7 @@ use clippy_utils::{method_chain_args, path_def_id}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_lint::LateContext; -use rustc_lint::Lint; +use rustc_lint::{LateContext, Lint}; use rustc_middle::ty; /// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints. diff --git a/clippy_lints/src/methods/chars_cmp_with_unwrap.rs b/clippy_lints/src/methods/chars_cmp_with_unwrap.rs index 27a05337a290..934b398c45f6 100644 --- a/clippy_lints/src/methods/chars_cmp_with_unwrap.rs +++ b/clippy_lints/src/methods/chars_cmp_with_unwrap.rs @@ -5,8 +5,7 @@ use if_chain::if_chain; use rustc_ast::ast; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_lint::LateContext; -use rustc_lint::Lint; +use rustc_lint::{LateContext, Lint}; /// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints with `unwrap()`. pub(super) fn check( diff --git a/clippy_lints/src/methods/clone_on_copy.rs b/clippy_lints/src/methods/clone_on_copy.rs index 3795c0ec2509..7eb325ee7b5e 100644 --- a/clippy_lints/src/methods/clone_on_copy.rs +++ b/clippy_lints/src/methods/clone_on_copy.rs @@ -1,15 +1,15 @@ -use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::get_parent_node; use clippy_utils::source::snippet_with_context; -use clippy_utils::sugg; use clippy_utils::ty::is_copy; use rustc_errors::Applicability; use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, MatchSource, Node, PatKind, QPath}; use rustc_lint::LateContext; -use rustc_middle::ty::{self, adjustment::Adjust, print::with_forced_trimmed_paths}; +use rustc_middle::ty::adjustment::Adjust; +use rustc_middle::ty::print::with_forced_trimmed_paths; +use rustc_middle::ty::{self}; use rustc_span::symbol::{sym, Symbol}; -use super::CLONE_DOUBLE_REF; use super::CLONE_ON_COPY; /// Checks for the `CLONE_ON_COPY` lint. @@ -42,41 +42,7 @@ pub(super) fn check( let ty = cx.typeck_results().expr_ty(expr); if let ty::Ref(_, inner, _) = arg_ty.kind() { - if let ty::Ref(_, innermost, _) = inner.kind() { - span_lint_and_then( - cx, - CLONE_DOUBLE_REF, - expr.span, - &with_forced_trimmed_paths!(format!( - "using `clone` on a double-reference; \ - this will copy the reference of type `{ty}` instead of cloning the inner type" - )), - |diag| { - if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) { - let mut ty = innermost; - let mut n = 0; - while let ty::Ref(_, inner, _) = ty.kind() { - ty = inner; - n += 1; - } - let refs = "&".repeat(n + 1); - let derefs = "*".repeat(n); - let explicit = with_forced_trimmed_paths!(format!("<{refs}{ty}>::clone({snip})")); - diag.span_suggestion( - expr.span, - "try dereferencing it", - with_forced_trimmed_paths!(format!("{refs}({derefs}{}).clone()", snip.deref())), - Applicability::MaybeIncorrect, - ); - diag.span_suggestion( - expr.span, - "or try being explicit if you are sure, that you want to clone a reference", - explicit, - Applicability::MaybeIncorrect, - ); - } - }, - ); + if let ty::Ref(..) = inner.kind() { return; // don't report clone_on_copy } } diff --git a/clippy_lints/src/methods/clone_on_ref_ptr.rs b/clippy_lints/src/methods/clone_on_ref_ptr.rs index 5e8ad0861f33..ddf3c9f27df2 100644 --- a/clippy_lints/src/methods/clone_on_ref_ptr.rs +++ b/clippy_lints/src/methods/clone_on_ref_ptr.rs @@ -42,7 +42,7 @@ pub(super) fn check( CLONE_ON_REF_PTR, expr.span, "using `.clone()` on a ref-counted pointer", - "try this", + "try", format!("{caller_type}::<{}>::clone(&{snippet})", subst.type_at(0)), app, ); diff --git a/clippy_lints/src/methods/collapsible_str_replace.rs b/clippy_lints/src/methods/collapsible_str_replace.rs index 5e01ed90ff09..5409ede6008b 100644 --- a/clippy_lints/src/methods/collapsible_str_replace.rs +++ b/clippy_lints/src/methods/collapsible_str_replace.rs @@ -8,8 +8,7 @@ use rustc_hir as hir; use rustc_lint::LateContext; use std::collections::VecDeque; -use super::method_call; -use super::COLLAPSIBLE_STR_REPLACE; +use super::{method_call, COLLAPSIBLE_STR_REPLACE}; pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, diff --git a/clippy_lints/src/methods/drain_collect.rs b/clippy_lints/src/methods/drain_collect.rs new file mode 100644 index 000000000000..eff2ab6f5dc6 --- /dev/null +++ b/clippy_lints/src/methods/drain_collect.rs @@ -0,0 +1,138 @@ +use crate::methods::DRAIN_COLLECT; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_range_full; +use clippy_utils::source::snippet; +use clippy_utils::ty::is_type_lang_item; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, LangItem, Path, QPath}; +use rustc_lint::LateContext; +use rustc_middle::query::Key; +<<<<<<< HEAD +<<<<<<< HEAD +use rustc_middle::ty; +<<<<<<< HEAD +======= +>>>>>>> 2748ab956 (new lint: `drain_collect`) +use rustc_middle::ty::Ty; +<<<<<<< HEAD +======= +use rustc_middle::ty; +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) +======= +use rustc_middle::ty::Ty; +>>>>>>> 3f3657a3e (make clippy happy) +use rustc_span::sym; +use rustc_span::Symbol; +======= +use rustc_span::{sym, Symbol}; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) + +/// Checks if both types match the given diagnostic item, e.g.: +/// +/// `vec![1,2].drain(..).collect::>()` +/// ^^^^^^^^^ ^^^^^^ true +/// `vec![1,2].drain(..).collect::>()` +/// ^^^^^^^^^ ^^^^^^^^^^ false +fn types_match_diagnostic_item(cx: &LateContext<'_>, expr: Ty<'_>, recv: Ty<'_>, sym: Symbol) -> bool { + if let Some(expr_adt_did) = expr.ty_adt_id() + && let Some(recv_adt_did) = recv.ty_adt_id() + { + cx.tcx.is_diagnostic_item(sym, expr_adt_did) && cx.tcx.is_diagnostic_item(sym, recv_adt_did) + } else { + false + } +} + +/// Checks `std::{vec::Vec, collections::VecDeque}`. +fn check_vec(cx: &LateContext<'_>, args: &[Expr<'_>], expr: Ty<'_>, recv: Ty<'_>, recv_path: &Path<'_>) -> bool { + (types_match_diagnostic_item(cx, expr, recv, sym::Vec) + || types_match_diagnostic_item(cx, expr, recv, sym::VecDeque)) + && matches!(args, [arg] if is_range_full(cx, arg, Some(recv_path))) +} + +/// Checks `std::string::String` +fn check_string(cx: &LateContext<'_>, args: &[Expr<'_>], expr: Ty<'_>, recv: Ty<'_>, recv_path: &Path<'_>) -> bool { + is_type_lang_item(cx, expr, LangItem::String) + && is_type_lang_item(cx, recv, LangItem::String) + && matches!(args, [arg] if is_range_full(cx, arg, Some(recv_path))) +} + +/// Checks `std::collections::{HashSet, HashMap, BinaryHeap}`. +fn check_collections(cx: &LateContext<'_>, expr: Ty<'_>, recv: Ty<'_>) -> Option<&'static str> { + types_match_diagnostic_item(cx, expr, recv, sym::HashSet) + .then_some("HashSet") + .or_else(|| types_match_diagnostic_item(cx, expr, recv, sym::HashMap).then_some("HashMap")) + .or_else(|| types_match_diagnostic_item(cx, expr, recv, sym::BinaryHeap).then_some("BinaryHeap")) +} + +pub(super) fn check(cx: &LateContext<'_>, args: &[Expr<'_>], expr: &Expr<'_>, recv: &Expr<'_>) { + let expr_ty = cx.typeck_results().expr_ty(expr); +<<<<<<< HEAD +<<<<<<< HEAD + let recv_ty = cx.typeck_results().expr_ty(recv); + let recv_ty_no_refs = recv_ty.peel_refs(); + + if let ExprKind::Path(QPath::Resolved(_, recv_path)) = recv.kind + && let Some(typename) = check_vec(cx, args, expr_ty, recv_ty_no_refs, recv_path) + .then_some("Vec") + .or_else(|| check_string(cx, args, expr_ty, recv_ty_no_refs, recv_path).then_some("String")) + .or_else(|| check_collections(cx, expr_ty, recv_ty_no_refs)) + { + let recv = snippet(cx, recv.span, ""); + let sugg = if let ty::Ref(..) = recv_ty.kind() { + format!("std::mem::take({recv})") + } else { + format!("std::mem::take(&mut {recv})") + }; + +<<<<<<< HEAD +======= + let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs(); +======= + let recv_ty = cx.typeck_results().expr_ty(recv); + let recv_ty_no_refs = recv_ty.peel_refs(); +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) + + if let ExprKind::Path(QPath::Resolved(_, recv_path)) = recv.kind + && let Some(typename) = check_vec(cx, args, expr_ty, recv_ty_no_refs, recv_path) + .then_some("Vec") + .or_else(|| check_string(cx, args, expr_ty, recv_ty_no_refs, recv_path).then_some("String")) + .or_else(|| check_collections(cx, expr_ty, recv_ty_no_refs)) + { + let recv = snippet(cx, recv.span, ""); +>>>>>>> 2748ab956 (new lint: `drain_collect`) +======= +>>>>>>> 5821fbbc3 (add test case for not whole length, move sugg into variable) + span_lint_and_sugg( + cx, + DRAIN_COLLECT, + expr.span, + &format!("you seem to be trying to move all elements into a new `{typename}`"), + "consider using `mem::take`", +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + sugg, +======= + format!("std::mem::take(&mut {recv})"), +>>>>>>> 2748ab956 (new lint: `drain_collect`) +======= + match recv_ty.kind() { + ty::Ref(..) => format!("std::mem::take({recv})"), + _ => format!("std::mem::take(&mut {recv})"), +======= + if let ty::Ref(..) = recv_ty.kind() { + format!("std::mem::take({recv})") + } else { + format!("std::mem::take(&mut {recv})") +>>>>>>> 3f3657a3e (make clippy happy) + }, +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) +======= + sugg, +>>>>>>> 5821fbbc3 (add test case for not whole length, move sugg into variable) + Applicability::MachineApplicable, + ); + } +} diff --git a/clippy_lints/src/methods/err_expect.rs b/clippy_lints/src/methods/err_expect.rs index ae03da0d3f9c..98f470dff8a2 100644 --- a/clippy_lints/src/methods/err_expect.rs +++ b/clippy_lints/src/methods/err_expect.rs @@ -1,8 +1,7 @@ use super::ERR_EXPECT; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::ty::has_debug_impl; -use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::ty::{has_debug_impl, is_type_diagnostic_item}; use rustc_errors::Applicability; use rustc_lint::LateContext; use rustc_middle::ty; diff --git a/clippy_lints/src/methods/expect_fun_call.rs b/clippy_lints/src/methods/expect_fun_call.rs index 92d21bb89326..862a7cec7751 100644 --- a/clippy_lints/src/methods/expect_fun_call.rs +++ b/clippy_lints/src/methods/expect_fun_call.rs @@ -144,7 +144,7 @@ pub(super) fn check<'tcx>( EXPECT_FUN_CALL, span_replace_word, &format!("use of `{name}` followed by a function call"), - "try this", + "try", format!("unwrap_or_else({closure_args} panic!({sugg}))"), applicability, ); @@ -162,7 +162,7 @@ pub(super) fn check<'tcx>( EXPECT_FUN_CALL, span_replace_word, &format!("use of `{name}` followed by a function call"), - "try this", + "try", format!("unwrap_or_else({closure_args} {{ panic!(\"{{}}\", {arg_root_snippet}) }})"), applicability, ); diff --git a/clippy_lints/src/methods/extend_with_drain.rs b/clippy_lints/src/methods/extend_with_drain.rs index 37b28463527c..495b266529bd 100644 --- a/clippy_lints/src/methods/extend_with_drain.rs +++ b/clippy_lints/src/methods/extend_with_drain.rs @@ -31,7 +31,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: EXTEND_WITH_DRAIN, expr.span, "use of `extend` instead of `append` for adding the full range of a second vector", - "try this", + "try", format!( "{}.append({}{})", snippet_with_applicability(cx, recv.span, "..", &mut applicability), diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs index fc80f2eeae01..597a423b5377 100644 --- a/clippy_lints/src/methods/filter_map.rs +++ b/clippy_lints/src/methods/filter_map.rs @@ -13,9 +13,7 @@ use rustc_span::source_map::Span; use rustc_span::symbol::{sym, Symbol}; use std::borrow::Cow; -use super::MANUAL_FILTER_MAP; -use super::MANUAL_FIND_MAP; -use super::OPTION_FILTER_MAP; +use super::{MANUAL_FILTER_MAP, MANUAL_FIND_MAP, OPTION_FILTER_MAP}; fn is_method(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Symbol) -> bool { match &expr.kind { diff --git a/clippy_lints/src/methods/filter_map_identity.rs b/clippy_lints/src/methods/filter_map_identity.rs index d1b5e945dfda..3337b250c0e7 100644 --- a/clippy_lints/src/methods/filter_map_identity.rs +++ b/clippy_lints/src/methods/filter_map_identity.rs @@ -3,7 +3,8 @@ use clippy_utils::{is_expr_identity_function, is_trait_method}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::{source_map::Span, sym}; +use rustc_span::source_map::Span; +use rustc_span::sym; use super::FILTER_MAP_IDENTITY; diff --git a/clippy_lints/src/methods/filter_map_next.rs b/clippy_lints/src/methods/filter_map_next.rs index 175e04f8ac06..3f89e5931487 100644 --- a/clippy_lints/src/methods/filter_map_next.rs +++ b/clippy_lints/src/methods/filter_map_next.rs @@ -31,7 +31,7 @@ pub(super) fn check<'tcx>( FILTER_MAP_NEXT, expr.span, msg, - "try this", + "try", format!("{iter_snippet}.find_map({filter_snippet})"), Applicability::MachineApplicable, ); diff --git a/clippy_lints/src/methods/filter_next.rs b/clippy_lints/src/methods/filter_next.rs index edcec0fc1015..ce7f9997b5a6 100644 --- a/clippy_lints/src/methods/filter_next.rs +++ b/clippy_lints/src/methods/filter_next.rs @@ -1,6 +1,7 @@ -use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; +use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; use clippy_utils::source::snippet; use clippy_utils::ty::implements_trait; +use rustc_ast::{BindingAnnotation, Mutability}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; @@ -8,6 +9,21 @@ use rustc_span::sym; use super::FILTER_NEXT; +fn path_to_local(expr: &hir::Expr<'_>) -> Option { + match expr.kind { + hir::ExprKind::Field(f, _) => path_to_local(f), + hir::ExprKind::Index(recv, _) => path_to_local(recv), + hir::ExprKind::Path(hir::QPath::Resolved( + _, + hir::Path { + res: rustc_hir::def::Res::Local(local), + .. + }, + )) => Some(*local), + _ => None, + } +} + /// lint use of `filter().next()` for `Iterators` pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, @@ -26,15 +42,30 @@ pub(super) fn check<'tcx>( if filter_snippet.lines().count() <= 1 { let iter_snippet = snippet(cx, recv.span, ".."); // add note if not multi-line - span_lint_and_sugg( - cx, - FILTER_NEXT, - expr.span, - msg, - "try this", - format!("{iter_snippet}.find({filter_snippet})"), - Applicability::MachineApplicable, - ); + span_lint_and_then(cx, FILTER_NEXT, expr.span, msg, |diag| { + let (applicability, pat) = if let Some(id) = path_to_local(recv) + && let Some(hir::Node::Pat(pat)) = cx.tcx.hir().find(id) + && let hir::PatKind::Binding(BindingAnnotation(_, Mutability::Not), _, ident, _) = pat.kind + { + (Applicability::Unspecified, Some((pat.span, ident))) + } else { + (Applicability::MachineApplicable, None) + }; + + diag.span_suggestion( + expr.span, + "try", + format!("{iter_snippet}.find({filter_snippet})"), + applicability, + ); + + if let Some((pat_span, ident)) = pat { + diag.span_help( + pat_span, + format!("you will also need to make `{ident}` mutable, because `find` takes `&mut self`"), + ); + } + }); } else { span_lint(cx, FILTER_NEXT, expr.span, msg); } diff --git a/clippy_lints/src/methods/flat_map_identity.rs b/clippy_lints/src/methods/flat_map_identity.rs index 6f911d79d0bc..84a21de0ac86 100644 --- a/clippy_lints/src/methods/flat_map_identity.rs +++ b/clippy_lints/src/methods/flat_map_identity.rs @@ -3,7 +3,8 @@ use clippy_utils::{is_expr_identity_function, is_trait_method}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::{source_map::Span, sym}; +use rustc_span::source_map::Span; +use rustc_span::sym; use super::FLAT_MAP_IDENTITY; diff --git a/clippy_lints/src/methods/flat_map_option.rs b/clippy_lints/src/methods/flat_map_option.rs index 615bde941334..367a8ae82bd8 100644 --- a/clippy_lints/src/methods/flat_map_option.rs +++ b/clippy_lints/src/methods/flat_map_option.rs @@ -4,7 +4,8 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::{source_map::Span, sym}; +use rustc_span::source_map::Span; +use rustc_span::sym; use super::FLAT_MAP_OPTION; use clippy_utils::ty::is_type_diagnostic_item; diff --git a/clippy_lints/src/methods/get_unwrap.rs b/clippy_lints/src/methods/get_unwrap.rs index ffc3a4d780e5..d1d2d9bf4875 100644 --- a/clippy_lints/src/methods/get_unwrap.rs +++ b/clippy_lints/src/methods/get_unwrap.rs @@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::get_parent_expr; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_type_diagnostic_item; -use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; @@ -23,21 +22,35 @@ pub(super) fn check<'tcx>( let mut applicability = Applicability::MachineApplicable; let expr_ty = cx.typeck_results().expr_ty(recv); let get_args_str = snippet_with_applicability(cx, get_arg.span, "..", &mut applicability); - let mut needs_ref; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> bdb2a1710 (declare needs_ref later) let caller_type = if derefs_to_slice(cx, recv, expr_ty).is_some() { - needs_ref = get_args_str.parse::().is_ok(); +<<<<<<< HEAD "slice" } else if is_type_diagnostic_item(cx, expr_ty, sym::Vec) { - needs_ref = get_args_str.parse::().is_ok(); "Vec" } else if is_type_diagnostic_item(cx, expr_ty, sym::VecDeque) { - needs_ref = get_args_str.parse::().is_ok(); +======= + needs_ref = true; +======= + let mut needs_ref = true; + let caller_type = if derefs_to_slice(cx, recv, expr_ty).is_some() { +>>>>>>> 3122e3d78 (use let chains, move assignments out of block, add tests) + "slice" + } else if is_type_diagnostic_item(cx, expr_ty, sym::Vec) { + "Vec" + } else if is_type_diagnostic_item(cx, expr_ty, sym::VecDeque) { +<<<<<<< HEAD + needs_ref = true; +>>>>>>> 6331c943f (include a ref if argument is not just a numeric literal) +======= +>>>>>>> 3122e3d78 (use let chains, move assignments out of block, add tests) "VecDeque" } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym::HashMap) { - needs_ref = true; "HashMap" } else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym::BTreeMap) { - needs_ref = true; "BTreeMap" } else { return; // caller is not a type that we want to lint @@ -45,18 +58,69 @@ pub(super) fn check<'tcx>( let mut span = expr.span; - // Handle the case where the result is immediately dereferenced - // by not requiring ref and pulling the dereference into the - // suggestion. + // Handle the case where the result is immediately dereferenced, + // either directly be the user, or as a result of a method call or the like + // by not requiring an explicit reference +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + let needs_ref = if let Some(parent) = get_parent_expr(cx, expr) + && let hir::ExprKind::Unary(hir::UnOp::Deref, _) + | hir::ExprKind::MethodCall(..) + | hir::ExprKind::Field(..) + | hir::ExprKind::Index(..) = parent.kind + { + if let hir::ExprKind::Unary(hir::UnOp::Deref, _) = parent.kind { + // if the user explicitly dereferences the result, we can adjust + // the span to also include the deref part + span = parent.span; +======= if_chain! { if needs_ref; if let Some(parent) = get_parent_expr(cx, expr); - if let hir::ExprKind::Unary(hir::UnOp::Deref, _) = parent.kind; + if let hir::ExprKind::Unary(hir::UnOp::Deref, _) + | hir::ExprKind::MethodCall(..) + | hir::ExprKind::Field(..) + | hir::ExprKind::Index(..) = parent.kind; then { + if let hir::ExprKind::Unary(hir::UnOp::Deref, _) = parent.kind { + // if the user explicitly dereferences the result, we can adjust + // the span to also include the deref part + span = parent.span; + } needs_ref = false; +>>>>>>> 6331c943f (include a ref if argument is not just a numeric literal) + } + false + } else { + true + }; +======= + if needs_ref + && let Some(parent) = get_parent_expr(cx, expr) +======= + let needs_ref = if let Some(parent) = get_parent_expr(cx, expr) +>>>>>>> bdb2a1710 (declare needs_ref later) + && let hir::ExprKind::Unary(hir::UnOp::Deref, _) + | hir::ExprKind::MethodCall(..) + | hir::ExprKind::Field(..) + | hir::ExprKind::Index(..) = parent.kind + { + if let hir::ExprKind::Unary(hir::UnOp::Deref, _) = parent.kind { + // if the user explicitly dereferences the result, we can adjust + // the span to also include the deref part span = parent.span; } +<<<<<<< HEAD + needs_ref = false; } +>>>>>>> 3122e3d78 (use let chains, move assignments out of block, add tests) +======= + false + } else { + true + }; +>>>>>>> bdb2a1710 (declare needs_ref later) let mut_str = if is_mut { "_mut" } else { "" }; let borrow_str = if !needs_ref { @@ -72,7 +136,7 @@ pub(super) fn check<'tcx>( GET_UNWRAP, span, &format!("called `.get{mut_str}().unwrap()` on a {caller_type}. Using `[]` is more clear and more concise"), - "try this", + "try", format!( "{borrow_str}{}[{get_args_str}]", snippet_with_applicability(cx, recv.span, "..", &mut applicability) diff --git a/clippy_lints/src/methods/inspect_for_each.rs b/clippy_lints/src/methods/inspect_for_each.rs index 7fd3ef1a622a..23cc192c38e3 100644 --- a/clippy_lints/src/methods/inspect_for_each.rs +++ b/clippy_lints/src/methods/inspect_for_each.rs @@ -2,7 +2,8 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::is_trait_method; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::{source_map::Span, sym}; +use rustc_span::source_map::Span; +use rustc_span::sym; use super::INSPECT_FOR_EACH; diff --git a/clippy_lints/src/methods/is_digit_ascii_radix.rs b/clippy_lints/src/methods/is_digit_ascii_radix.rs index 301aff5ae6ac..120f3d5f42c7 100644 --- a/clippy_lints/src/methods/is_digit_ascii_radix.rs +++ b/clippy_lints/src/methods/is_digit_ascii_radix.rs @@ -1,10 +1,10 @@ //! Lint for `c.is_digit(10)` use super::IS_DIGIT_ASCII_RADIX; +use clippy_utils::consts::{constant_full_int, FullInt}; +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::{ - consts::constant_full_int, consts::FullInt, diagnostics::span_lint_and_sugg, source::snippet_with_applicability, -}; +use clippy_utils::source::snippet_with_applicability; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index c87f5daab6f2..674d34517481 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -9,8 +9,7 @@ use clippy_utils::visitors::is_local_used; use rustc_hir::{BindingAnnotation, Body, BorrowKind, ByRef, Expr, ExprKind, Mutability, Pat, PatKind}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty; -use rustc_span::sym; -use rustc_span::Span; +use rustc_span::{sym, Span}; /// lint use of: /// - `hashmap.iter().map(|(_, v)| v)` diff --git a/clippy_lints/src/methods/iter_nth.rs b/clippy_lints/src/methods/iter_nth.rs index ceee12784cbb..121043104058 100644 --- a/clippy_lints/src/methods/iter_nth.rs +++ b/clippy_lints/src/methods/iter_nth.rs @@ -20,9 +20,9 @@ pub(super) fn check<'tcx>( let caller_type = if derefs_to_slice(cx, iter_recv, cx.typeck_results().expr_ty(iter_recv)).is_some() { "slice" } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(iter_recv), sym::Vec) { - "Vec" + "`Vec`" } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(iter_recv), sym::VecDeque) { - "VecDeque" + "`VecDeque`" } else { iter_nth_zero::check(cx, expr, nth_recv, nth_arg); return; // caller is not a type that we want to lint diff --git a/clippy_lints/src/methods/iter_nth_zero.rs b/clippy_lints/src/methods/iter_nth_zero.rs index c830958d5c80..af9f3e0f9901 100644 --- a/clippy_lints/src/methods/iter_nth_zero.rs +++ b/clippy_lints/src/methods/iter_nth_zero.rs @@ -1,8 +1,8 @@ use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::is_trait_method; use clippy_utils::source::snippet_with_applicability; -use if_chain::if_chain; +use clippy_utils::{is_lang_item_or_ctor, is_trait_method}; +use hir::{LangItem, OwnerNode}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; @@ -11,9 +11,31 @@ use rustc_span::sym; use super::ITER_NTH_ZERO; pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 242807a9c (Don't lint `iter_nth_zero` in `next`) + if let OwnerNode::Item(item) = cx.tcx.hir().owner(cx.tcx.hir().get_parent_item(expr.hir_id)) + && let def_id = item.owner_id.to_def_id() + && is_trait_method(cx, expr, sym::Iterator) + && let Some(Constant::Int(0)) = constant(cx, cx.typeck_results(), arg) + && !is_lang_item_or_ctor(cx, def_id, LangItem::IteratorNext) + { + let mut app = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + ITER_NTH_ZERO, + expr.span, + "called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent", + "try calling `.next()` instead of `.nth(0)`", + format!("{}.next()", snippet_with_applicability(cx, recv.span, "..", &mut app)), + app, + ); +<<<<<<< HEAD +======= if_chain! { if is_trait_method(cx, expr, sym::Iterator); - if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), arg); + if let Some(Constant::Int(0)) = constant(cx, cx.typeck_results(), arg); then { let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( @@ -26,5 +48,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr applicability, ); } +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) +======= +>>>>>>> 242807a9c (Don't lint `iter_nth_zero` in `next`) } } diff --git a/clippy_lints/src/methods/iter_overeager_cloned.rs b/clippy_lints/src/methods/iter_overeager_cloned.rs index b4210d875104..9f7ec19aa598 100644 --- a/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -51,7 +51,7 @@ pub(super) fn check<'tcx>( if let Some(mut snip) = snippet_opt(cx, method_span) { snip.push_str(trailing_clone); let replace_span = expr.span.with_lo(cloned_recv.span.hi()); - diag.span_suggestion(replace_span, "try this", snip, Applicability::MachineApplicable); + diag.span_suggestion(replace_span, "try", snip, Applicability::MachineApplicable); } } ); diff --git a/clippy_lints/src/methods/iter_skip_next.rs b/clippy_lints/src/methods/iter_skip_next.rs index 279175e20c37..39af52141bbc 100644 --- a/clippy_lints/src/methods/iter_skip_next.rs +++ b/clippy_lints/src/methods/iter_skip_next.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::is_trait_method; -use clippy_utils::path_to_local; use clippy_utils::source::snippet; +use clippy_utils::{is_trait_method, path_to_local}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::{BindingAnnotation, Node, PatKind}; diff --git a/clippy_lints/src/methods/iter_with_drain.rs b/clippy_lints/src/methods/iter_with_drain.rs index f6772c5c6b36..2ab721ace848 100644 --- a/clippy_lints/src/methods/iter_with_drain.rs +++ b/clippy_lints/src/methods/iter_with_drain.rs @@ -21,7 +21,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span ITER_WITH_DRAIN, span.with_hi(expr.span.hi()), &format!("`drain(..)` used on a `{ty_name}`"), - "try this", + "try", "into_iter()".to_string(), Applicability::MaybeIncorrect, ); diff --git a/clippy_lints/src/methods/iterator_step_by_zero.rs b/clippy_lints/src/methods/iterator_step_by_zero.rs index 64c09214a768..b631cd00cda4 100644 --- a/clippy_lints/src/methods/iterator_step_by_zero.rs +++ b/clippy_lints/src/methods/iterator_step_by_zero.rs @@ -9,7 +9,7 @@ use super::ITERATOR_STEP_BY_ZERO; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, arg: &'tcx hir::Expr<'_>) { if is_trait_method(cx, expr, sym::Iterator) { - if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), arg) { + if let Some(Constant::Int(0)) = constant(cx, cx.typeck_results(), arg) { span_lint( cx, ITERATOR_STEP_BY_ZERO, diff --git a/clippy_lints/src/methods/join_absolute_paths.rs b/clippy_lints/src/methods/join_absolute_paths.rs new file mode 100644 index 000000000000..a4eeda3cce53 --- /dev/null +++ b/clippy_lints/src/methods/join_absolute_paths.rs @@ -0,0 +1,30 @@ +use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item}; +use rustc_ast::ast::LitKind; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_span::{symbol::sym::Path, Span}; + +use super::JOIN_ABSOLUTE_PATHS; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, join_arg: &'tcx Expr<'tcx>, span: Span) { + let ty = cx.typeck_results().expr_ty(expr); + if_chain!( + if is_type_diagnostic_item(cx, ty, Path); + let applicability = Applicability::MachineApplicable; + if let ExprKind::Lit(spanned) = &join_arg.kind; + if let LitKind::Str(symbol, _) = spanned.node; + if symbol.as_str().starts_with('/') || symbol.as_str().starts_with('\\'); + then { + span_lint_and_sugg( + cx, + JOIN_ABSOLUTE_PATHS, + span.with_hi(expr.span.hi()), + r#"argument in join called on path contains a starting '/'"#, + "try removing first '/' or '\\'", + "join(\"your/path/here\")".to_owned(), + applicability + ); + } + ); +} diff --git a/clippy_lints/src/methods/join_absolute_paths.rs~ b/clippy_lints/src/methods/join_absolute_paths.rs~ new file mode 100644 index 000000000000..bf8f8dfb6ad8 --- /dev/null +++ b/clippy_lints/src/methods/join_absolute_paths.rs~ @@ -0,0 +1,30 @@ +use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item}; +use rustc_ast::ast::LitKind; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_span::{symbol::sym::Path, Span}; + +use super::JOIN_ABSOLUTE_PATHSS; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, join_arg: &'tcx Expr<'tcx>, span: Span) { + let ty = cx.typeck_results().expr_ty(expr); + if_chain!( + if is_type_diagnostic_item(cx, ty, Path); + let applicability = Applicability::MachineApplicable; + if let ExprKind::Lit(spanned) = &join_arg.kind; + if let LitKind::Str(symbol, _) = spanned.node; + if symbol.as_str().starts_with('/') || symbol.as_str().starts_with('\\'); + then { + span_lint_and_sugg( + cx, + JOIN_ABSOLUTE_PATHSS, + span.with_hi(expr.span.hi()), + r#"argument in join called on path contains a starting '/'"#, + "try removing first '/' or '\\'", + "join(\"your/path/here\")".to_owned(), + applicability + ); + } + ); +} diff --git a/clippy_lints/src/methods/manual_next_back.rs b/clippy_lints/src/methods/manual_next_back.rs new file mode 100644 index 000000000000..5f3fec53827a --- /dev/null +++ b/clippy_lints/src/methods/manual_next_back.rs @@ -0,0 +1,38 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_trait_method; +use clippy_utils::ty::implements_trait; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_span::symbol::sym; + +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'_>, + rev_call: &'tcx Expr<'_>, + rev_recv: &'tcx Expr<'_>, +) { + let rev_recv_ty = cx.typeck_results().expr_ty(rev_recv); + + // check that the receiver of `rev` implements `DoubleEndedIterator` and + // that `rev` and `next` come from `Iterator` + if cx + .tcx + .get_diagnostic_item(sym::DoubleEndedIterator) + .map_or(false, |double_ended_iterator| { + implements_trait(cx, rev_recv_ty, double_ended_iterator, &[]) + }) + && is_trait_method(cx, rev_call, sym::Iterator) + && is_trait_method(cx, expr, sym::Iterator) + { + span_lint_and_sugg( + cx, + super::MANUAL_NEXT_BACK, + expr.span.with_lo(rev_recv.span.hi()), + "manual backwards iteration", + "use", + String::from(".next_back()"), + Applicability::MachineApplicable, + ); + } +} diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs index a7284c644977..7e62e7ad909e 100644 --- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs +++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs @@ -24,10 +24,8 @@ pub fn check( let Some(mm) = is_min_or_max(cx, unwrap_arg) else { return }; if ty.is_signed() { - use self::{ - MinMax::{Max, Min}, - Sign::{Neg, Pos}, - }; + use self::MinMax::{Max, Min}; + use self::Sign::{Neg, Pos}; let Some(sign) = lit_sign(arith_rhs) else { return; diff --git a/clippy_lints/src/methods/manual_str_repeat.rs b/clippy_lints/src/methods/manual_str_repeat.rs index a08f7254053f..ab13d30d8452 100644 --- a/clippy_lints/src/methods/manual_str_repeat.rs +++ b/clippy_lints/src/methods/manual_str_repeat.rs @@ -88,7 +88,7 @@ pub(super) fn check( MANUAL_STR_REPEAT, collect_expr.span, "manual implementation of `str::repeat` using iterators", - "try this", + "try", format!("{val_str}.repeat({count_snip})"), app ) diff --git a/clippy_lints/src/methods/manual_try_fold.rs b/clippy_lints/src/methods/manual_try_fold.rs new file mode 100644 index 000000000000..fcb2aab169b1 --- /dev/null +++ b/clippy_lints/src/methods/manual_try_fold.rs @@ -0,0 +1,74 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_from_proc_macro; +use clippy_utils::msrvs::{Msrv, ITERATOR_TRY_FOLD}; +use clippy_utils::source::snippet_opt; +use clippy_utils::ty::implements_trait; +use rustc_errors::Applicability; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::{LateContext, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_span::Span; + +use super::MANUAL_TRY_FOLD; + +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &Expr<'tcx>, + init: &Expr<'_>, + acc: &Expr<'_>, + fold_span: Span, + msrv: &Msrv, +) { + if !in_external_macro(cx.sess(), fold_span) + && msrv.meets(ITERATOR_TRY_FOLD) + && let init_ty = cx.typeck_results().expr_ty(init) + && let Some(try_trait) = cx.tcx.lang_items().try_trait() + && implements_trait(cx, init_ty, try_trait, &[]) + && let ExprKind::Call(path, [first, rest @ ..]) = init.kind + && let ExprKind::Path(qpath) = path.kind + && let Res::Def(DefKind::Ctor(_, _), _) = cx.qpath_res(&qpath, path.hir_id) + && let ExprKind::Closure(closure) = acc.kind +<<<<<<< HEAD +<<<<<<< HEAD + && !is_from_proc_macro(cx, expr) + && let Some(args_snip) = closure.fn_arg_span.and_then(|fn_arg_span| snippet_opt(cx, fn_arg_span)) +======= + && let Some(args_snip) = closure.fn_arg_span.and_then(|fn_arg_span| snippet_opt(cx, fn_arg_span)) + && !is_from_proc_macro(cx, expr) +>>>>>>> 354172a18 (New lint `manual_try_fold`) +======= + && !is_from_proc_macro(cx, expr) + && let Some(args_snip) = closure.fn_arg_span.and_then(|fn_arg_span| snippet_opt(cx, fn_arg_span)) +>>>>>>> 04b085769 (Typo) + { + let init_snip = rest + .is_empty() + .then_some(first.span) + .and_then(|span| snippet_opt(cx, span)) + .unwrap_or("...".to_owned()); + + span_lint_and_sugg( + cx, + MANUAL_TRY_FOLD, + fold_span, +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> cb5d7e344 (address comments) + "usage of `Iterator::fold` on a type that implements `Try`", + "use `try_fold` instead", + format!("try_fold({init_snip}, {args_snip} ...)", ), +======= + "you seem to be using `Iterator::fold` on a type that implements `Try`", + "use `try_fold` instead", +<<<<<<< HEAD + format!("try_fold({init_snip}, {args_snip}, ...)", ), +>>>>>>> 354172a18 (New lint `manual_try_fold`) +======= + format!("try_fold({init_snip}, {args_snip} ...)", ), +>>>>>>> 04b085769 (Typo) + Applicability::HasPlaceholders, + ); + } +} diff --git a/clippy_lints/src/methods/map_collect_result_unit.rs b/clippy_lints/src/methods/map_collect_result_unit.rs index a0300d278709..36c7ddc973cf 100644 --- a/clippy_lints/src/methods/map_collect_result_unit.rs +++ b/clippy_lints/src/methods/map_collect_result_unit.rs @@ -25,7 +25,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, iter: &hir::Expr MAP_COLLECT_RESULT_UNIT, expr.span, "`.map().collect()` can be replaced with `.try_for_each()`", - "try this", + "try", format!( "{}.try_for_each({})", snippet(cx, iter.span, ".."), diff --git a/clippy_lints/src/methods/map_flatten.rs b/clippy_lints/src/methods/map_flatten.rs index 361ffcb5ef3f..349caa6ea6c2 100644 --- a/clippy_lints/src/methods/map_flatten.rs +++ b/clippy_lints/src/methods/map_flatten.rs @@ -6,7 +6,8 @@ use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::{symbol::sym, Span}; +use rustc_span::symbol::sym; +use rustc_span::Span; use super::MAP_FLATTEN; diff --git a/clippy_lints/src/methods/map_identity.rs b/clippy_lints/src/methods/map_identity.rs index 0f25ef82ed42..7be1ce483f63 100644 --- a/clippy_lints/src/methods/map_identity.rs +++ b/clippy_lints/src/methods/map_identity.rs @@ -4,7 +4,8 @@ use clippy_utils::{is_expr_identity_function, is_trait_method}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::{source_map::Span, sym}; +use rustc_span::source_map::Span; +use rustc_span::sym; use super::MAP_IDENTITY; diff --git a/clippy_lints/src/methods/map_unwrap_or.rs b/clippy_lints/src/methods/map_unwrap_or.rs index 3122f72ee915..5464e455dea4 100644 --- a/clippy_lints/src/methods/map_unwrap_or.rs +++ b/clippy_lints/src/methods/map_unwrap_or.rs @@ -11,7 +11,8 @@ use rustc_span::symbol::sym; use super::MAP_UNWRAP_OR; /// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s -/// Return true if lint triggered +/// +/// Returns true if the lint was emitted pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, @@ -63,7 +64,7 @@ pub(super) fn check<'tcx>( MAP_UNWRAP_OR, expr.span, msg, - "try this", + "try", format!("{var_snippet}.map_or_else({unwrap_snippet}, {map_snippet})"), Applicability::MachineApplicable, ); diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 2904727fec76..674d6ab26887 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -14,6 +14,7 @@ mod clone_on_copy; mod clone_on_ref_ptr; mod cloned_instead_of_copied; mod collapsible_str_replace; +mod drain_collect; mod err_expect; mod expect_fun_call; mod expect_used; @@ -45,9 +46,22 @@ mod iter_overeager_cloned; mod iter_skip_next; mod iter_with_drain; mod iterator_step_by_zero; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +mod join_absolute_path; +======= +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +======= +mod join_absolute_paths; +>>>>>>> 85f4cccf4 (renamed lint) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +mod manual_next_back; mod manual_ok_or; mod manual_saturating_arithmetic; mod manual_str_repeat; +mod manual_try_fold; mod map_clone; mod map_collect_result_unit; mod map_err_ignore; @@ -68,8 +82,8 @@ mod option_map_unwrap_or; mod or_fun_call; mod or_then_unwrap; mod path_buf_push_overwrite; -mod path_join_correction; mod range_zip_with_len; +mod read_line_without_trim; mod repeat_once; mod search_is_some; mod seek_from_current; @@ -86,6 +100,7 @@ mod suspicious_command_arg_space; mod suspicious_map; mod suspicious_splitn; mod suspicious_to_owned; +mod type_id_on_box; mod uninit_assumed_init; mod unit_hash; mod unnecessary_filter_map; @@ -93,6 +108,7 @@ mod unnecessary_fold; mod unnecessary_iter_cloned; mod unnecessary_join; mod unnecessary_lazy_eval; +mod unnecessary_literal_unwrap; mod unnecessary_sort_by; mod unnecessary_to_owned; mod unwrap_or_else_default; @@ -273,6 +289,88 @@ declare_clippy_lint! { "using `.unwrap()` on `Result` or `Option`, which should at least get a better message using `expect()`" } +declare_clippy_lint! { + /// ### What it does +<<<<<<< HEAD +<<<<<<< HEAD + /// Checks for `.unwrap()` related calls on `Result`s and `Option`s that are constructed. + /// + /// ### Why is this bad? + /// It is better to write the value directly without the indirection. + /// + /// ### Examples + /// ```rust + /// let val1 = Some(1).unwrap(); + /// let val2 = Ok::<_, ()>(1).unwrap(); + /// let val3 = Err::<(), _>(1).unwrap_err(); +======= + /// Checks for `.unwrap()` or `.unwrap_err()` calls on `Result`s and `.unwrap()` call on `Option`s. +======= + /// Checks for `.unwrap()` related calls on `Result`s and `Option`s that are constructed. +>>>>>>> 6e4c5561b (Preserve type annotations when present) + /// + /// ### Why is this bad? + /// It is better to write the value directly without the indirection. + /// + /// ### Examples + /// ```rust +<<<<<<< HEAD + /// # let option = Some(1); + /// # let result: Result = Ok(1); + /// option.unwrap(); + /// result.unwrap(); +>>>>>>> e707447a8 (Boilerplate for the new lint) +======= + /// let val1 = Some(1).unwrap(); + /// let val2 = Ok::<_, ()>(1).unwrap(); + /// let val3 = Err::<(), _>(1).unwrap_err(); +>>>>>>> 6e4c5561b (Preserve type annotations when present) + /// ``` + /// + /// Use instead: + /// ```rust +<<<<<<< HEAD +<<<<<<< HEAD + /// let val1 = 1; + /// let val2 = 1; + /// let val3 = 1; +======= + /// # let option = Some(1); + /// # let result: Result = Ok(1); + /// option.expect("more helpful message"); + /// result.expect("more helpful message"); + /// ``` + /// + /// If [expect_used](#expect_used) is enabled, instead: + /// ```rust,ignore + /// # let option = Some(1); + /// # let result: Result = Ok(1); + /// option?; + /// + /// // or + /// + /// result?; +>>>>>>> e707447a8 (Boilerplate for the new lint) +======= + /// let val1 = 1; + /// let val2 = 1; + /// let val3 = 1; +>>>>>>> 6e4c5561b (Preserve type annotations when present) + /// ``` + #[clippy::version = "1.69.0"] + pub UNNECESSARY_LITERAL_UNWRAP, + complexity, +<<<<<<< HEAD +<<<<<<< HEAD + "using `unwrap()` related calls on `Result` and `Option` constructors" +======= + "checks for calls of `unwrap()` or `expect()` on `Some()` that cannot fail" +>>>>>>> e707447a8 (Boilerplate for the new lint) +======= + "using `unwrap()` related calls on `Result` and `Option` constructors" +>>>>>>> 6e4c5561b (Preserve type annotations when present) +} + declare_clippy_lint! { /// ### What it does /// Checks for `.expect()` or `.expect_err()` calls on `Result`s and `.expect()` call on `Option`s. @@ -485,6 +583,7 @@ declare_clippy_lint! { /// # let result: Result = Ok(1); /// # fn some_function(foo: ()) -> usize { 1 } /// option.map(|a| a + 1).unwrap_or(0); + /// option.map(|a| a > 10).unwrap_or(false); /// result.map(|a| a + 1).unwrap_or_else(some_function); /// ``` /// @@ -494,6 +593,7 @@ declare_clippy_lint! { /// # let result: Result = Ok(1); /// # fn some_function(foo: ()) -> usize { 1 } /// option.map_or(0, |a| a + 1); + /// option.is_some_and(|a| a > 10); /// result.map_or_else(some_function, |a| a + 1); /// ``` #[clippy::version = "1.45.0"] @@ -985,29 +1085,6 @@ declare_clippy_lint! { "using 'clone' on a ref-counted pointer" } -declare_clippy_lint! { - /// ### What it does - /// Checks for usage of `.clone()` on an `&&T`. - /// - /// ### Why is this bad? - /// Cloning an `&&T` copies the inner `&T`, instead of - /// cloning the underlying `T`. - /// - /// ### Example - /// ```rust - /// fn main() { - /// let x = vec![1]; - /// let y = &&x; - /// let z = y.clone(); - /// println!("{:p} {:p}", *y, z); // prints out the same pointer - /// } - /// ``` - #[clippy::version = "pre 1.29.0"] - pub CLONE_DOUBLE_REF, - correctness, - "using `clone` on `&&T`" -} - declare_clippy_lint! { /// ### What it does /// Checks for usage of `.to_string()` on an `&&T` where @@ -2917,6 +2994,37 @@ declare_clippy_lint! { "use of sort() when sort_unstable() is equivalent" } +declare_clippy_lint! { + /// ### What it does + /// Looks for calls to ` as Any>::type_id`. + /// + /// ### Why is this bad? + /// This most certainly does not do what the user expects and is very easy to miss. + /// Calling `type_id` on a `Box` calls `type_id` on the `Box<..>` itself, + /// so this will return the `TypeId` of the `Box` type (not the type id + /// of the value referenced by the box!). + /// + /// ### Example + /// ```rust,ignore + /// use std::any::{Any, TypeId}; + /// + /// let any_box: Box = Box::new(42_i32); + /// assert_eq!(any_box.type_id(), TypeId::of::()); // ⚠️ this fails! + /// ``` + /// Use instead: + /// ```rust + /// use std::any::{Any, TypeId}; + /// + /// let any_box: Box = Box::new(42_i32); + /// assert_eq!((*any_box).type_id(), TypeId::of::()); + /// // ^ dereference first, to call `type_id` on `dyn Any` + /// ``` + #[clippy::version = "1.72.0"] + pub TYPE_ID_ON_BOX, + suspicious, + "calling `.type_id()` on `Box`" +} + declare_clippy_lint! { /// ### What it does /// Detects `().hash(_)`. @@ -3156,8 +3264,11 @@ declare_clippy_lint! { /// ### Example /// ```rust /// # let iterator = vec![1].into_iter(); - /// let len = iterator.clone().collect::>().len(); - /// // should be + /// let len = iterator.collect::>().len(); + /// ``` + /// Use instead: + /// ```rust + /// # let iterator = vec![1].into_iter(); /// let len = iterator.count(); /// ``` #[clippy::version = "1.30.0"] @@ -3186,7 +3297,7 @@ declare_clippy_lint! { /// ```rust /// std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap(); /// ``` - #[clippy::version = "1.67.0"] + #[clippy::version = "1.69.0"] pub SUSPICIOUS_COMMAND_ARG_SPACE, suspicious, "single command line argument that looks like it should be multiple arguments" @@ -3211,33 +3322,298 @@ declare_clippy_lint! { /// let mut v = vec![1, 2, 3]; /// v.clear(); /// ``` - #[clippy::version = "1.69.0"] + #[clippy::version = "1.70.0"] pub CLEAR_WITH_DRAIN, nursery, "calling `drain` in order to `clear` a container" } +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD declare_clippy_lint! { +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +declare_clippy_lint! { +<<<<<<< HEAD /// ### What it does - /// Checks for initial '/' in an argument to .join on a path. +<<<<<<< HEAD +>>>>>>> 08a8a81af (Rebase and merge attempt number 2.) + /// Checks for initial `'/'` in an argument to `.join()` on a `Path`. +======= +<<<<<<< HEAD + /// Checks for initial `'/ or \\'` in an argument to `.join()` on a `Path`. +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) + /// + /// ### Why is this bad? + /// `.join()` comments starting with a separator (`/` or `\\`) can replace the entire path. +======= + /// Checks for initial `'/'` in an argument to `.join()` on a `Path`. + /// /// ### Why is this bad? - /// .join() calls on paths already attach the '/'. + /// `.join()` comments starting with a separator, can replace the entire path. +>>>>>>> e4f5d83fa (Fixed formatting.) + /// If this is intentional, prefer creating a new `Path` instead. + /// + /// See [`Path::join()`](https://doc.rust-lang.org/std/path/struct.Path.html#method.join) + /// /// ### Example /// ```rust - /// // example code where clippy issues a warning /// let path = std::path::Path::new("/bin"); - /// path.join("/sh"); + /// let res = path.join("/sh"); +<<<<<<< HEAD + /// assert_eq!(res, std::path::PathBuf::from("/sh")); /// ``` - /// Use instead: + /// + /// Use instead; /// ```rust - /// // path.join("sh"); + /// let path = std::path::Path::new("/bin"); + /// + /// // If this was unintentional, remove the leading separator + /// let extend = path.join("sh"); + /// assert_eq!(extend, std::path::PathBuf::from("/bin/sh")); + /// + /// // If this was intentional, create a new path instead + /// let new = std::path::Path::new("/sh"); + /// assert_eq!(new, std::path::PathBuf::from("/sh")); /// ``` #[clippy::version = "1.70.0"] - pub PATH_JOIN_CORRECTION, + pub JOIN_ABSOLUTE_PATHS, pedantic, +<<<<<<< HEAD "arg to .join called on a Path contains '/' at the start" } +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +======= +>>>>>>> a8834bc46 (add lint `manual_next_back`) +======= + "arg to .join called on a Path contains '/' at the start" +} + +>>>>>>> 08a8a81af (Rebase and merge attempt number 2.) +declare_clippy_lint! { + /// ### What it does +======= +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) + /// Checks for `.rev().next()` on a `DoubleEndedIterator` + /// + /// ### Why is this bad? + /// `.next_back()` is cleaner. + /// + /// ### Example + /// ```rust + /// # let foo = [0; 10]; + /// foo.iter().rev().next(); +======= + /// assert_eq!(res, PathBuf::from("/sh")); +>>>>>>> e4f5d83fa (Fixed formatting.) + /// ``` + /// + /// Use instead: + /// ```rust +<<<<<<< HEAD + /// # let foo = [0; 10]; + /// foo.iter().next_back(); +======= + /// let path = std::path::Path::new("/bin"); + /// + /// // If this was unintentional, remove the leading separator + /// let extend = path.join("sh"); + /// assert_eq!(extend, PathBuf::from("/bin/sh")); + /// + /// // If this was intentional, create a new path instead + /// let new = Path::new("/sh") + /// assert_eq!(new PathBuf::from("/sh")); +>>>>>>> e4f5d83fa (Fixed formatting.) + /// ``` + #[clippy::version = "1.71.0"] + pub MANUAL_NEXT_BACK, + style, + "manual reverse iteration of `DoubleEndedIterator`" +} + +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> a8834bc46 (add lint `manual_next_back`) +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +>>>>>>> a8834bc46 (add lint `manual_next_back`) +======= +declare_clippy_lint! { + /// ### What it does + /// Checks for calls to `.drain()` that clear the collection, immediately followed by a call to `.collect()`. + /// + /// > "Collection" in this context refers to any type with a `drain` method: + /// > `Vec`, `VecDeque`, `BinaryHeap`, `HashSet`,`HashMap`, `String` + /// + /// ### Why is this bad? + /// Using `mem::take` is faster as it avoids the allocation. + /// When using `mem::take`, the old collection is replaced with an empty one and ownership of + /// the old collection is returned. + /// +<<<<<<< HEAD +<<<<<<< HEAD + /// ### Known issues +======= + /// ### Drawback +>>>>>>> 2748ab956 (new lint: `drain_collect`) +======= + /// ### Known issues +>>>>>>> 5821fbbc3 (add test case for not whole length, move sugg into variable) + /// `mem::take(&mut vec)` is almost equivalent to `vec.drain(..).collect()`, except that + /// it also moves the **capacity**. The user might have explicitly written it this way + /// to keep the capacity on the original `Vec`. + /// + /// ### Example + /// ```rust + /// fn remove_all(v: &mut Vec) -> Vec { + /// v.drain(..).collect() + /// } + /// ``` + /// Use instead: + /// ```rust + /// use std::mem; + /// fn remove_all(v: &mut Vec) -> Vec { + /// mem::take(v) + /// } + /// ``` + #[clippy::version = "1.71.0"] + pub DRAIN_COLLECT, + perf, +<<<<<<< HEAD +<<<<<<< HEAD + "calling `.drain(..).collect()` to move all elements into a new collection" +} + +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of `Iterator::fold` with a type that implements `Try`. + /// + /// ### Why is this bad? +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> cb5d7e344 (address comments) + /// The code should use `try_fold` instead, which short-circuits on failure, thus opening the + /// door for additional optimizations not possible with `fold` as rustc can guarantee the + /// function is never called on `None`, `Err`, etc., alleviating otherwise necessary checks. It's + /// also slightly more idiomatic. +<<<<<<< HEAD +======= + /// This should use `try_fold` instead, which short-circuits on failure, thus opening the door + /// for additional optimizations not possible with `fold` as rustc can guarantee the function is + /// never called on `None`, `Err`, etc., alleviating otherwise necessary checks. It's also + /// slightly more idiomatic. +>>>>>>> fbb3f759e (update docs) +======= +>>>>>>> cb5d7e344 (address comments) + /// + /// ### Known issues + /// This lint doesn't take into account whether a function does something on the failure case, + /// i.e., whether short-circuiting will affect behavior. Refactoring to `try_fold` is not + /// desirable in those cases. +<<<<<<< HEAD +======= + /// This is better represented with `try_fold`, but this has one major difference: It will + /// short-circuit on failure. *This is almost always what you want*. This can also open the door + /// for additional optimizations as well, as rustc can guarantee the function is never + /// called on `None`, `Err`, etc., alleviating otherwise necessary checks. +>>>>>>> 354172a18 (New lint `manual_try_fold`) +======= +>>>>>>> fbb3f759e (update docs) + /// + /// ### Example + /// ```rust + /// vec![1, 2, 3].iter().fold(Some(0i32), |sum, i| sum?.checked_add(*i)); + /// ``` + /// Use instead: + /// ```rust + /// vec![1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i)); + /// ``` + #[clippy::version = "1.72.0"] + pub MANUAL_TRY_FOLD, + perf, + "checks for usage of `Iterator::fold` with a type that implements `Try`" +<<<<<<< HEAD +======= + "description" +>>>>>>> 2748ab956 (new lint: `drain_collect`) +======= + "calling `.drain(..).collect()` to move all elements into a new collection" +>>>>>>> 20ae597ec (add a description) +======= +>>>>>>> 354172a18 (New lint `manual_try_fold`) +} + +declare_clippy_lint! { + /// Looks for calls to [`Stdin::read_line`] to read a line from the standard input + /// into a string, then later attempting to parse this string into a type without first trimming it, which will + /// always fail because the string has a trailing newline in it. + /// + /// ### Why is this bad? + /// The `.parse()` call will always fail. + /// + /// ### Example + /// ```rust,ignore + /// let mut input = String::new(); + /// std::io::stdin().read_line(&mut input).expect("Failed to read a line"); + /// let num: i32 = input.parse().expect("Not a number!"); + /// assert_eq!(num, 42); // we never even get here! + /// ``` + /// Use instead: + /// ```rust,ignore + /// let mut input = String::new(); + /// std::io::stdin().read_line(&mut input).expect("Failed to read a line"); + /// let num: i32 = input.trim_end().parse().expect("Not a number!"); + /// // ^^^^^^^^^^^ remove the trailing newline + /// assert_eq!(num, 42); + /// ``` + #[clippy::version = "1.72.0"] + pub READ_LINE_WITHOUT_TRIM, + correctness, + "calling `Stdin::read_line`, then trying to parse it without first trimming" +} + +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +declare_clippy_lint! { + /// ### What it does + /// Checks for `.rev().next()` on a `DoubleEndedIterator` + /// + /// ### Why is this bad? + /// `.next_back()` is cleaner. + /// + /// ### Example + /// ```rust + /// # let foo = [0; 10]; + /// foo.iter().rev().next(); + /// ``` + /// Use instead: + /// ```rust + /// # let foo = [0; 10]; + /// foo.iter().next_back(); + /// ``` + #[clippy::version = "1.71.0"] + pub MANUAL_NEXT_BACK, + style, + "manual reverse iteration of `DoubleEndedIterator`" +} + +>>>>>>> a8834bc46 (add lint `manual_next_back`) +>>>>>>> 4da6e7e06 (rebase attempt) pub struct Methods { avoid_breaking_exported_api: bool, msrv: Msrv, @@ -3280,7 +3656,6 @@ impl_lint_pass!(Methods => [ CHARS_LAST_CMP, CLONE_ON_COPY, CLONE_ON_REF_PTR, - CLONE_DOUBLE_REF, COLLAPSIBLE_STR_REPLACE, ITER_OVEREAGER_CLONED, CLONED_INSTEAD_OF_COPIED, @@ -3312,6 +3687,7 @@ impl_lint_pass!(Methods => [ STRING_EXTEND_CHARS, ITER_CLONED_COLLECT, ITER_WITH_DRAIN, + TYPE_ID_ON_BOX, USELESS_ASREF, UNNECESSARY_FOLD, UNNECESSARY_FILTER_MAP, @@ -3358,6 +3734,7 @@ impl_lint_pass!(Methods => [ REPEAT_ONCE, STABLE_SORT_PRIMITIVE, UNIT_HASH, + READ_LINE_WITHOUT_TRIM, UNNECESSARY_SORT_BY, VEC_RESIZE_TO_ZERO, VERBOSE_FILE_READS, @@ -3367,7 +3744,69 @@ impl_lint_pass!(Methods => [ NEEDLESS_COLLECT, SUSPICIOUS_COMMAND_ARG_SPACE, CLEAR_WITH_DRAIN, +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + PATH_JOIN_CORRECTION, +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + MANUAL_NEXT_BACK, +>>>>>>> a8834bc46 (add lint `manual_next_back`) +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + MANUAL_NEXT_BACK, +>>>>>>> a8834bc46 (add lint `manual_next_back`) +======= + PATH_JOIN_CORRECTION, +======= + JOIN_ABSOLUTE_PATH, +>>>>>>> 18bd97fdd (Renamed lint to join_absolute_path as per request.) + MANUAL_NEXT_BACK, +>>>>>>> 08a8a81af (Rebase and merge attempt number 2.) +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) + JOIN_ABSOLUTE_PATH, +======= +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +======= + JOIN_ABSOLUTE_PATHS, +>>>>>>> 85f4cccf4 (renamed lint) + MANUAL_NEXT_BACK, + UNNECESSARY_LITERAL_UNWRAP, +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + DRAIN_COLLECT, + MANUAL_TRY_FOLD, +======= +>>>>>>> 2902359b3 (Add the lint to the lib) +======= + DRAIN_COLLECT +>>>>>>> 2748ab956 (new lint: `drain_collect`) +======= + DRAIN_COLLECT, + MANUAL_TRY_FOLD, +>>>>>>> 354172a18 (New lint `manual_try_fold`) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= PATH_JOIN_CORRECTION, +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + MANUAL_NEXT_BACK, +>>>>>>> a8834bc46 (add lint `manual_next_back`) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) ]); /// Extracts a method call name, args, and `Span` of the method name. @@ -3523,8 +3962,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { let first_arg_span = first_arg_ty.span; let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty); let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()) - .self_ty() - .skip_binder(); + .self_ty(); wrong_self_convention::check( cx, item.ident.name.as_str(), @@ -3542,8 +3980,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { if let TraitItemKind::Fn(_, _) = item.kind; let ret_ty = return_ty(cx, item.owner_id); let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()) - .self_ty() - .skip_binder(); + .self_ty(); if !ret_ty.contains(self_ty); then { @@ -3599,6 +4036,9 @@ impl Methods { manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg); } }, + Some(("drain", recv, args, ..)) => { + drain_collect::check(cx, args, expr, recv); + } _ => {}, } }, @@ -3627,12 +4067,46 @@ impl Methods { case_sensitive_file_extension_comparisons::check(cx, expr, span, recv, arg); } }, - ("expect", [_]) => match method_call(recv) { - Some(("ok", recv, [], _, _)) => ok_expect::check(cx, expr, recv), - Some(("err", recv, [], err_span, _)) => err_expect::check(cx, expr, recv, span, err_span, &self.msrv), - _ => expect_used::check(cx, expr, recv, false, self.allow_expect_in_tests), + ("expect", [_]) => { + match method_call(recv) { + Some(("ok", recv, [], _, _)) => ok_expect::check(cx, expr, recv), + Some(("err", recv, [], err_span, _)) => err_expect::check(cx, expr, recv, span, err_span, &self.msrv), + _ => expect_used::check(cx, expr, recv, false, self.allow_expect_in_tests), + } +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 6e4dc93e2 (Support suggesting panics) + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); }, - ("expect_err", [_]) => expect_used::check(cx, expr, recv, true, self.allow_expect_in_tests), + ("expect_err", [_]) => { + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); +<<<<<<< HEAD + expect_used::check(cx, expr, recv, true, self.allow_expect_in_tests); +======= + if let ExprKind::Call(recv, _) = recv.kind { + unnecessary_literal_unwrap::check(cx, expr, recv, name); +======= + if let ExprKind::Call(recv, [arg]) = recv.kind { + unnecessary_literal_unwrap::check(cx, expr, recv, arg, name); +>>>>>>> daf619748 (Implement the suggestion) + } +>>>>>>> 21b88ce29 (Implement the lint for expect) +======= + unnecessary_literal_unwrap::check(cx, expr, recv, name); +>>>>>>> 8f8350298 (Recognize `unwrap_or` methods) + }, +<<<<<<< HEAD +======= + ("expect_err", [_]) => { + unnecessary_literal_unwrap::check(cx, expr, recv, name); +======= +>>>>>>> 6e4dc93e2 (Support suggesting panics) + expect_used::check(cx, expr, recv, true, self.allow_expect_in_tests); + }, +>>>>>>> 69af0e13b (Recognize `Err`) ("extend", [arg]) => { string_extend_chars::check(cx, expr, recv, arg); extend_with_drain::check(cx, expr, recv, arg); @@ -3653,7 +4127,10 @@ impl Methods { Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, true), _ => {}, }, - ("fold", [init, acc]) => unnecessary_fold::check(cx, expr, init, acc, span), + ("fold", [init, acc]) => { + manual_try_fold::check(cx, expr, init, acc, call_span, &self.msrv); + unnecessary_fold::check(cx, expr, init, acc, span); + }, ("for_each", [_]) => { if let Some(("inspect", _, [_], span2, _)) = method_call(recv) { inspect_for_each::check(cx, expr, span2); @@ -3678,7 +4155,11 @@ impl Methods { if let Some(("collect", _, _, span, _)) = method_call(recv) { unnecessary_join::check(cx, expr, recv, join_arg, span); } - else {path_join_correction::check(cx, expr, join_arg, span);} +<<<<<<< HEAD + else {join_absolute_paths::check(cx, expr, join_arg, span);} +======= + else {path_join_correction::check(cx, expr, join_arg, span);} +>>>>>>> e4f5d83fa (Fixed formatting.) }, ("last", []) | ("skip", [_]) => { if let Some((name2, recv2, args2, _span2, _)) = method_call(recv) { @@ -3727,6 +4208,7 @@ impl Methods { ("iter", []) => iter_next_slice::check(cx, expr, recv2), ("skip", [arg]) => iter_skip_next::check(cx, expr, recv2, arg), ("skip_while", [_]) => skip_while_next::check(cx, expr), + ("rev", [])=> manual_next_back::check(cx, expr, recv, recv2), _ => {}, } } @@ -3756,6 +4238,9 @@ impl Methods { ("read_to_string", [_]) => { verbose_file_reads::check(cx, expr, recv, verbose_file_reads::READ_TO_STRING_MSG); }, + ("read_line", [arg]) => { + read_line_without_trim::check(cx, expr, recv, arg); + } ("repeat", [arg]) => { repeat_once::check(cx, expr, recv, arg); }, @@ -3791,13 +4276,13 @@ impl Methods { unnecessary_sort_by::check(cx, expr, recv, arg, true); }, ("splitn" | "rsplitn", [count_arg, pat_arg]) => { - if let Some((Constant::Int(count), _)) = constant(cx, cx.typeck_results(), count_arg) { + if let Some(Constant::Int(count)) = constant(cx, cx.typeck_results(), count_arg) { suspicious_splitn::check(cx, name, expr, recv, count); str_splitn::check(cx, name, expr, recv, pat_arg, count, &self.msrv); } }, ("splitn_mut" | "rsplitn_mut", [count_arg, _]) => { - if let Some((Constant::Int(count), _)) = constant(cx, cx.typeck_results(), count_arg) { + if let Some(Constant::Int(count)) = constant(cx, cx.typeck_results(), count_arg) { suspicious_splitn::check(cx, name, expr, recv, count); } }, @@ -3824,6 +4309,9 @@ impl Methods { ("to_os_string" | "to_path_buf" | "to_vec", []) => { implicit_clone::check(cx, name, expr, recv); }, + ("type_id", []) => { + type_id_on_box::check(cx, recv, expr.span); + } ("unwrap", []) => { match method_call(recv) { Some(("get", recv, [get_arg], _, _)) => { @@ -3837,21 +4325,84 @@ impl Methods { }, _ => {}, } +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); +======= + if let ExprKind::Call(recv, _) = recv.kind { + unnecessary_literal_unwrap::check(cx, expr, recv, name); +======= + if let ExprKind::Call(recv, [arg]) = recv.kind { + unnecessary_literal_unwrap::check(cx, expr, recv, arg, name); +>>>>>>> daf619748 (Implement the suggestion) + } +>>>>>>> 0b1bb5fbf (Implement the lint) unwrap_used::check(cx, expr, recv, false, self.allow_unwrap_in_tests); }, - ("unwrap_err", []) => unwrap_used::check(cx, expr, recv, true, self.allow_unwrap_in_tests), - ("unwrap_or", [u_arg]) => match method_call(recv) { - Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), lhs, [rhs], _, _)) => { - manual_saturating_arithmetic::check(cx, expr, lhs, rhs, u_arg, &arith["checked_".len()..]); - }, - Some(("map", m_recv, [m_arg], span, _)) => { - option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span); - }, - Some(("then_some", t_recv, [t_arg], _, _)) => { - obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg); - }, - _ => {}, + ("unwrap_err", []) => { + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); + unwrap_used::check(cx, expr, recv, true, self.allow_unwrap_in_tests); + }, + ("unwrap_or", [u_arg]) => { + match method_call(recv) { + Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), lhs, [rhs], _, _)) => { + manual_saturating_arithmetic::check(cx, expr, lhs, rhs, u_arg, &arith["checked_".len()..]); + }, + Some(("map", m_recv, [m_arg], span, _)) => { + option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, &self.msrv); + }, + Some(("then_some", t_recv, [t_arg], _, _)) => { + obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg); + }, + _ => {}, + } + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); + }, + ("unwrap_or_default" | "unwrap_unchecked" | "unwrap_err_unchecked", []) => { + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); + } + ("unwrap_or_else", [u_arg]) => { + match method_call(recv) { + Some(("map", recv, [map_arg], _, _)) + if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, &self.msrv) => {}, + _ => { + unwrap_or_else_default::check(cx, expr, recv, u_arg); + unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or"); + }, + } + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); +======= + unnecessary_literal_unwrap::check(cx, expr, recv, name); +======= + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); +>>>>>>> 6e4dc93e2 (Support suggesting panics) + unwrap_used::check(cx, expr, recv, false, self.allow_unwrap_in_tests); + }, + ("unwrap_err", []) => { + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); + unwrap_used::check(cx, expr, recv, true, self.allow_unwrap_in_tests); }, + ("unwrap_or", [u_arg]) => { + match method_call(recv) { + Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), lhs, [rhs], _, _)) => { + manual_saturating_arithmetic::check(cx, expr, lhs, rhs, u_arg, &arith["checked_".len()..]); + }, + Some(("map", m_recv, [m_arg], span, _)) => { + option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, &self.msrv); + }, + Some(("then_some", t_recv, [t_arg], _, _)) => { + obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg); + }, + _ => {}, + } + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); + }, + ("unwrap_or_default", []) => { + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); + } +<<<<<<< HEAD ("unwrap_or_else", [u_arg]) => match method_call(recv) { Some(("map", recv, [map_arg], _, _)) if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, &self.msrv) => {}, @@ -3859,6 +4410,23 @@ impl Methods { unwrap_or_else_default::check(cx, expr, recv, u_arg); unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or"); }, +>>>>>>> 8f8350298 (Recognize `unwrap_or` methods) +======= + ("unwrap_or_else", [u_arg]) => { + match method_call(recv) { + Some(("map", recv, [map_arg], _, _)) + if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, &self.msrv) => {}, + _ => { + unwrap_or_else_default::check(cx, expr, recv, u_arg); + unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or"); + }, + } +<<<<<<< HEAD + unnecessary_literal_unwrap::check(cx, expr, recv, name); +>>>>>>> 7ed7283e0 (Recognize `unwrap_or_else` method) +======= + unnecessary_literal_unwrap::check(cx, expr, recv, name, args); +>>>>>>> 6e4dc93e2 (Support suggesting panics) }, ("zip", [arg]) => { if let ExprKind::MethodCall(name, iter_recv, [], _) = recv.kind diff --git a/clippy_lints/src/methods/mut_mutex_lock.rs b/clippy_lints/src/methods/mut_mutex_lock.rs index d0aa39d06275..161a7aa7fd4f 100644 --- a/clippy_lints/src/methods/mut_mutex_lock.rs +++ b/clippy_lints/src/methods/mut_mutex_lock.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::{expr_custom_deref_adjustment, ty::is_type_diagnostic_item}; +use clippy_utils::expr_custom_deref_adjustment; +use clippy_utils::ty::is_type_diagnostic_item; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Expr, Mutability}; diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index 0b0c6adc5045..9d853897b68a 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -1,12 +1,11 @@ use super::NEEDLESS_COLLECT; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; -use clippy_utils::higher; use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{is_type_diagnostic_item, make_normalized_projection, make_projection}; use clippy_utils::{ - can_move_expr_to_closure, get_enclosing_block, get_parent_node, is_trait_method, path_to_local, path_to_local_id, - CaptureKind, + can_move_expr_to_closure, fn_def_id, get_enclosing_block, get_parent_node, higher, is_trait_method, path_to_local, + path_to_local_id, CaptureKind, }; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, MultiSpan}; @@ -16,7 +15,11 @@ use rustc_hir::{ }; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{self, AssocKind, EarlyBinder, GenericArg, GenericArgKind, Ty}; +<<<<<<< HEAD +use rustc_middle::ty::{self, AssocKind, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty}; +======= +use rustc_middle::ty::{self, AssocKind, Clause, EarlyBinder, GenericArg, GenericArgKind, PredicateKind, Ty}; +>>>>>>> 84f89f30e (enhance `needless_collect`) use rustc_span::symbol::Ident; use rustc_span::{sym, Span, Symbol}; @@ -32,6 +35,8 @@ pub(super) fn check<'tcx>( if let Some(parent) = get_parent_node(cx.tcx, collect_expr.hir_id) { match parent { Node::Expr(parent) => { + check_collect_into_intoiterator(cx, parent, collect_expr, call_span, iter_expr); + if let ExprKind::MethodCall(name, _, args @ ([] | [_]), _) = parent.kind { let mut app = Applicability::MachineApplicable; let name = name.ident.as_str(); @@ -134,6 +139,72 @@ pub(super) fn check<'tcx>( } } +/// checks for for collecting into a (generic) method or function argument +/// taking an `IntoIterator` +fn check_collect_into_intoiterator<'tcx>( + cx: &LateContext<'tcx>, + parent: &'tcx Expr<'tcx>, + collect_expr: &'tcx Expr<'tcx>, + call_span: Span, + iter_expr: &'tcx Expr<'tcx>, +) { + if let Some(id) = fn_def_id(cx, parent) { + let args = match parent.kind { + ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) => args, + _ => &[], + }; + // find the argument index of the `collect_expr` in the + // function / method call + if let Some(arg_idx) = args.iter().position(|e| e.hir_id == collect_expr.hir_id).map(|i| { + if matches!(parent.kind, ExprKind::MethodCall(_, _, _, _)) { + i + 1 + } else { + i + } + }) { + // extract the input types of the function/method call + // that contains `collect_expr` + let inputs = cx + .tcx + .liberate_late_bound_regions(id, cx.tcx.fn_sig(id).subst_identity()) + .inputs(); + + // map IntoIterator generic bounds to their signature + // types and check whether the argument type is an + // `IntoIterator` + if cx + .tcx + .param_env(id) + .caller_bounds() + .into_iter() + .filter_map(|p| { +<<<<<<< HEAD + if let ClauseKind::Trait(t) = p.kind().skip_binder() +======= + if let PredicateKind::Clause(Clause::Trait(t)) = p.kind().skip_binder() +>>>>>>> 84f89f30e (enhance `needless_collect`) + && cx.tcx.is_diagnostic_item(sym::IntoIterator,t.trait_ref.def_id) { + Some(t.self_ty()) + } else { + None + } + }) + .any(|ty| ty == inputs[arg_idx]) + { + span_lint_and_sugg( + cx, + NEEDLESS_COLLECT, + call_span.with_lo(iter_expr.span.hi()), + NEEDLESS_COLLECT_MSG, + "remove this call", + String::new(), + Applicability::MachineApplicable, + ); + } + } + } +} + /// Checks if the given method call matches the expected signature of `([&[mut]] self) -> bool` fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool { cx.typeck_results().type_dependent_def_id(call_id).map_or(false, |id| { @@ -151,7 +222,7 @@ fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, item, [collect_ty]) && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions( cx.param_env, - cx.tcx.mk_projection(into_iter_item_proj.def_id, into_iter_item_proj.substs) + Ty::new_projection(cx.tcx,into_iter_item_proj.def_id, into_iter_item_proj.substs) ) { iter_item_ty == into_iter_item_ty @@ -174,10 +245,10 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) - .associated_items(iter_trait) .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait) && let substs = cx.tcx.mk_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) - && let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs) + && let proj_ty = Ty::new_projection(cx.tcx,iter_item.def_id, substs) && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty) { - item_ty == EarlyBinder(search_ty).subst(cx.tcx, cx.typeck_results().node_substs(call_id)) + item_ty == EarlyBinder::bind(search_ty).subst(cx.tcx, cx.typeck_results().node_substs(call_id)) } else { false } @@ -258,7 +329,7 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> { fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { // Check function calls on our collection - if let ExprKind::MethodCall(method_name, recv, [args @ ..], _) = &expr.kind { + if let ExprKind::MethodCall(method_name, recv, args, _) = &expr.kind { if method_name.ident.name == sym!(collect) && is_trait_method(self.cx, expr, sym::Iterator) { self.current_mutably_captured_ids = get_captured_ids(self.cx, self.cx.typeck_results().expr_ty(recv)); self.visit_expr(recv); diff --git a/clippy_lints/src/methods/needless_option_as_deref.rs b/clippy_lints/src/methods/needless_option_as_deref.rs index 7030baf19ff5..c18bfa1b8026 100644 --- a/clippy_lints/src/methods/needless_option_as_deref.rs +++ b/clippy_lints/src/methods/needless_option_as_deref.rs @@ -29,7 +29,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, name NEEDLESS_OPTION_AS_DEREF, expr.span, "derefed type is same as origin", - "try this", + "try", snippet_opt(cx, recv.span).unwrap(), Applicability::MachineApplicable, ); diff --git a/clippy_lints/src/methods/obfuscated_if_else.rs b/clippy_lints/src/methods/obfuscated_if_else.rs index 4d7427b26621..697eab32a33b 100644 --- a/clippy_lints/src/methods/obfuscated_if_else.rs +++ b/clippy_lints/src/methods/obfuscated_if_else.rs @@ -1,7 +1,6 @@ -// run-rustfix - use super::OBFUSCATED_IF_ELSE; -use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet_with_applicability}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_with_applicability; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; diff --git a/clippy_lints/src/methods/open_options.rs b/clippy_lints/src/methods/open_options.rs index c6a27cdd6fac..23d23f25f14c 100644 --- a/clippy_lints/src/methods/open_options.rs +++ b/clippy_lints/src/methods/open_options.rs @@ -48,7 +48,7 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec .. } = *span { - if lit { Argument::True } else { Argument::False } + if *lit { Argument::True } else { Argument::False } } else { // The function is called with a literal which is not a boolean literal. // This is theoretically possible, but not very likely. diff --git a/clippy_lints/src/methods/option_map_or_none.rs b/clippy_lints/src/methods/option_map_or_none.rs index 41ceef19e3a9..cb6a2306857d 100644 --- a/clippy_lints/src/methods/option_map_or_none.rs +++ b/clippy_lints/src/methods/option_map_or_none.rs @@ -8,8 +8,7 @@ use rustc_hir::LangItem::{OptionNone, OptionSome}; use rustc_lint::LateContext; use rustc_span::symbol::sym; -use super::OPTION_MAP_OR_NONE; -use super::RESULT_MAP_OR_INTO_OPTION; +use super::{OPTION_MAP_OR_NONE, RESULT_MAP_OR_INTO_OPTION}; // The expression inside a closure may or may not have surrounding braces // which causes problems when generating a suggestion. diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs index 4c6328481e43..e21950c1b6e0 100644 --- a/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -1,19 +1,21 @@ use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::ty::is_copy; -use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::ty::{is_copy, is_type_diagnostic_item}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; +use rustc_hir::def::Res; use rustc_hir::intravisit::{walk_path, Visitor}; -use rustc_hir::{self, HirId, Path}; +use rustc_hir::{self, ExprKind, HirId, Node, PatKind, Path, QPath}; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; use rustc_span::source_map::Span; -use rustc_span::{sym, Symbol}; +use rustc_span::sym; use super::MAP_UNWRAP_OR; /// lint use of `map().unwrap_or()` for `Option`s +#[expect(clippy::too_many_arguments)] pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &rustc_hir::Expr<'_>, @@ -22,12 +24,27 @@ pub(super) fn check<'tcx>( unwrap_recv: &rustc_hir::Expr<'_>, unwrap_arg: &'tcx rustc_hir::Expr<'_>, map_span: Span, + msrv: &Msrv, ) { // lint if the caller of `map()` is an `Option` if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option) { if !is_copy(cx, cx.typeck_results().expr_ty(unwrap_arg)) { - // Do not lint if the `map` argument uses identifiers in the `map` - // argument that are also used in the `unwrap_or` argument + // Replacing `.map().unwrap_or()` with `.map_or(, )` can sometimes lead to + // borrowck errors, see #10579 for one such instance. + // In particular, if `a` causes a move and `f` references that moved binding, then we cannot lint: + // ``` + // let x = vec![1, 2]; + // x.get(0..1).map(|s| s.to_vec()).unwrap_or(x); + // ``` + // This compiles, but changing it to `map_or` will produce a compile error: + // ``` + // let x = vec![1, 2]; + // x.get(0..1).map_or(x, |s| s.to_vec()) + // ^ moving `x` here + // ^^^^^^^^^^^ while it is borrowed here (and later used in the closure) + // ``` + // So, we have to check that `a` is not referenced anywhere (even outside of the `.map` closure!) + // before the call to `unwrap_or`. let mut unwrap_visitor = UnwrapVisitor { cx, @@ -35,14 +52,18 @@ pub(super) fn check<'tcx>( }; unwrap_visitor.visit_expr(unwrap_arg); - let mut map_expr_visitor = MapExprVisitor { + let mut reference_visitor = ReferenceVisitor { cx, identifiers: unwrap_visitor.identifiers, - found_identifier: false, + found_reference: false, + unwrap_or_span: unwrap_arg.span, }; - map_expr_visitor.visit_expr(map_arg); - if map_expr_visitor.found_identifier { + let map = cx.tcx.hir(); + let body = map.body(map.body_owned_by(map.enclosing_body_owner(expr.hir_id))); + reference_visitor.visit_body(body); + + if reference_visitor.found_reference { return; } } @@ -51,16 +72,47 @@ pub(super) fn check<'tcx>( return; } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a693cbc1b (changed msrv name for consistency & changed nested if for style) + // is_some_and is stabilised && `unwrap_or` argument is false; suggest `is_some_and` instead + let suggest_is_some_and = msrv.meets(msrvs::OPTION_IS_SOME_AND) + && matches!(&unwrap_arg.kind, ExprKind::Lit(lit) + if matches!(lit.node, rustc_ast::LitKind::Bool(false))); +<<<<<<< HEAD +======= + let mut suggest_is_some_and = false; + // argument to `unwrap_or` is false & is_some_and is stabilised; should suggest using `is_some_and` + if msrv.meets(msrvs::OPT_IS_SOME_AND) { + if let ExprKind::Lit(unwrap_lit) = &unwrap_arg.kind { + if let rustc_ast::LitKind::Bool(false) = unwrap_lit.node { + suggest_is_some_and = true; + } + } + } +>>>>>>> 9b7d8d1dc (suggests `is_some_and` over `map().unwrap_or(false)`) +======= +>>>>>>> a693cbc1b (changed msrv name for consistency & changed nested if for style) + let mut applicability = Applicability::MachineApplicable; // get snippet for unwrap_or() let unwrap_snippet = snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability); // lint message // comparing the snippet from source to raw text ("None") below is safe // because we already have checked the type. - let arg = if unwrap_snippet == "None" { "None" } else { "" }; + let arg = if unwrap_snippet == "None" { + "None" + } else if suggest_is_some_and { + "false" + } else { + "" + }; let unwrap_snippet_none = unwrap_snippet == "None"; let suggest = if unwrap_snippet_none { "and_then()" + } else if suggest_is_some_and { + "is_some_and()" } else { "map_or(, )" }; @@ -75,12 +127,18 @@ pub(super) fn check<'tcx>( let mut suggestion = vec![ ( map_span, - String::from(if unwrap_snippet_none { "and_then" } else { "map_or" }), + String::from(if unwrap_snippet_none { + "and_then" + } else if suggest_is_some_and { + "is_some_and" + } else { + "map_or" + }), ), (expr.span.with_lo(unwrap_recv.span.hi()), String::new()), ]; - if !unwrap_snippet_none { + if !unwrap_snippet_none && !suggest_is_some_and { suggestion.push((map_arg_span.with_hi(map_arg_span.lo()), format!("{unwrap_snippet}, "))); } @@ -91,14 +149,19 @@ pub(super) fn check<'tcx>( struct UnwrapVisitor<'a, 'tcx> { cx: &'a LateContext<'tcx>, - identifiers: FxHashSet, + identifiers: FxHashSet, } impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> { type NestedFilter = nested_filter::All; - fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) { - self.identifiers.insert(ident(path)); + fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) { + if let Res::Local(local_id) = path.res + && let Some(Node::Pat(pat)) = self.cx.tcx.hir().find(local_id) + && let PatKind::Binding(_, local_id, ..) = pat.kind + { + self.identifiers.insert(local_id); + } walk_path(self, path); } @@ -107,32 +170,35 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> { } } -struct MapExprVisitor<'a, 'tcx> { +struct ReferenceVisitor<'a, 'tcx> { cx: &'a LateContext<'tcx>, - identifiers: FxHashSet, - found_identifier: bool, + identifiers: FxHashSet, + found_reference: bool, + unwrap_or_span: Span, } -impl<'a, 'tcx> Visitor<'tcx> for MapExprVisitor<'a, 'tcx> { +impl<'a, 'tcx> Visitor<'tcx> for ReferenceVisitor<'a, 'tcx> { type NestedFilter = nested_filter::All; - - fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) { - if self.identifiers.contains(&ident(path)) { - self.found_identifier = true; - return; + fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'_>) { + // If we haven't found a reference yet, check if this references + // one of the locals that was moved in the `unwrap_or` argument. + // We are only interested in exprs that appear before the `unwrap_or` call. + if !self.found_reference { + if expr.span < self.unwrap_or_span + && let ExprKind::Path(ref path) = expr.kind + && let QPath::Resolved(_, path) = path + && let Res::Local(local_id) = path.res + && let Some(Node::Pat(pat)) = self.cx.tcx.hir().find(local_id) + && let PatKind::Binding(_, local_id, ..) = pat.kind + && self.identifiers.contains(&local_id) + { + self.found_reference = true; + } + rustc_hir::intravisit::walk_expr(self, expr); } - walk_path(self, path); } fn nested_visit_map(&mut self) -> Self::Map { self.cx.tcx.hir() } } - -fn ident(path: &Path<'_>) -> Symbol { - path.segments - .last() - .expect("segments should be composed of at least 1 element") - .ident - .name -} diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index 7ce28ea93e01..9165c1248f0a 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -62,7 +62,7 @@ pub(super) fn check<'tcx>( OR_FUN_CALL, method_span.with_hi(span.hi()), &format!("use of `{name}` followed by a call to `{path}`"), - "try this", + "try", format!("{sugg}()"), Applicability::MachineApplicable, ); @@ -139,7 +139,7 @@ pub(super) fn check<'tcx>( OR_FUN_CALL, span_replace_word, &format!("use of `{name}` followed by a function call"), - "try this", + "try", format!("{name}_{suffix}({sugg})"), app, ); diff --git a/clippy_lints/src/methods/or_then_unwrap.rs b/clippy_lints/src/methods/or_then_unwrap.rs index 55ba6e262df7..7b0bdcf99e73 100644 --- a/clippy_lints/src/methods/or_then_unwrap.rs +++ b/clippy_lints/src/methods/or_then_unwrap.rs @@ -1,8 +1,10 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::{diagnostics::span_lint_and_sugg, is_res_lang_ctor, path_res}; +use clippy_utils::{is_res_lang_ctor, path_res}; use rustc_errors::Applicability; -use rustc_hir::{lang_items::LangItem, Expr, ExprKind}; +use rustc_hir::lang_items::LangItem; +use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; use rustc_span::{sym, Span}; @@ -50,7 +52,7 @@ pub(super) fn check<'tcx>( OR_THEN_UNWRAP, unwrap_expr.span.with_lo(or_span.lo()), title, - "try this", + "try", suggestion, applicability, ); diff --git a/clippy_lints/src/methods/path_join_correction.rs b/clippy_lints/src/methods/path_join_correction.rs index 1be8e79e262c..441eef7124d6 100644 --- a/clippy_lints/src/methods/path_join_correction.rs +++ b/clippy_lints/src/methods/path_join_correction.rs @@ -10,21 +10,21 @@ use super::PATH_JOIN_CORRECTION; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, join_arg: &'tcx Expr<'tcx>, span: Span) { let ty = cx.typeck_results().expr_ty(expr); if_chain!( - if is_type_diagnostic_item(cx, ty, Path); - let applicability = Applicability::MachineApplicable; - if let ExprKind::Lit(spanned) = &join_arg.kind; - if let LitKind::Str(symbol, _) = spanned.node; - if symbol.as_str().starts_with('/') || symbol.as_str().starts_with('\\'); + if is_type_diagnostic_item(cx, ty, Path); + let applicability = Applicability::MachineApplicable; + if let ExprKind::Lit(spanned) = &join_arg.kind; + if let LitKind::Str(symbol, _) = spanned.node; + if symbol.as_str().starts_with('/') || symbol.as_str().starts_with('\\'); then { span_lint_and_sugg( cx, PATH_JOIN_CORRECTION, span.with_hi(expr.span.hi()), - r#"argument in join called on path contains a starting '/'"#, - "try removing first '/' or '\\'", - "join(\"your/path/here\")".to_owned(), - applicability - ); - } - ); + r#"argument in join called on path contains a starting '/'"#, + "try removing first '/' or '\\'", + "join(\"your/path/here\")".to_owned(), + applicability + ); + } + ); } diff --git a/clippy_lints/src/methods/range_zip_with_len.rs b/clippy_lints/src/methods/range_zip_with_len.rs index 867a3b402377..f253d8de91f9 100644 --- a/clippy_lints/src/methods/range_zip_with_len.rs +++ b/clippy_lints/src/methods/range_zip_with_len.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::source::snippet; -use clippy_utils::{higher, SpanlessEq}; -use clippy_utils::{is_integer_const, is_trait_method}; +use clippy_utils::{higher, is_integer_const, is_trait_method, SpanlessEq}; use if_chain::if_chain; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::LateContext; diff --git a/clippy_lints/src/methods/read_line_without_trim.rs b/clippy_lints/src/methods/read_line_without_trim.rs new file mode 100644 index 000000000000..8add0656101e --- /dev/null +++ b/clippy_lints/src/methods/read_line_without_trim.rs @@ -0,0 +1,74 @@ +use std::ops::ControlFlow; + +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::source::snippet; +use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::visitors::for_each_local_use_after_expr; +use clippy_utils::{get_parent_expr, match_def_path}; +use rustc_errors::Applicability; +use rustc_hir::def::Res; +use rustc_hir::{Expr, ExprKind, QPath}; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty}; +use rustc_span::sym; + +use super::READ_LINE_WITHOUT_TRIM; + +/// Will a `.parse::()` call fail if the input has a trailing newline? +fn parse_fails_on_trailing_newline(ty: Ty<'_>) -> bool { + // only allow a very limited set of types for now, for which we 100% know parsing will fail + matches!(ty.kind(), ty::Float(_) | ty::Bool | ty::Int(_) | ty::Uint(_)) +} + +pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) { + if let Some(recv_adt) = cx.typeck_results().expr_ty(recv).ty_adt_def() + && match_def_path(cx, recv_adt.did(), &["std", "io", "stdio", "Stdin"]) + && let ExprKind::Path(QPath::Resolved(_, path)) = arg.peel_borrows().kind + && let Res::Local(local_id) = path.res + { + // We've checked that `call` is a call to `Stdin::read_line()` with the right receiver, + // now let's check if the first use of the string passed to `::read_line()` is + // parsed into a type that will always fail if it has a trailing newline. + for_each_local_use_after_expr(cx, local_id, call.hir_id, |expr| { + if let Some(parent) = get_parent_expr(cx, expr) + && let ExprKind::MethodCall(segment, .., span) = parent.kind + && segment.ident.name == sym!(parse) + && let parse_result_ty = cx.typeck_results().expr_ty(parent) + && is_type_diagnostic_item(cx, parse_result_ty, sym::Result) + && let ty::Adt(_, substs) = parse_result_ty.kind() + && let Some(ok_ty) = substs[0].as_type() + && parse_fails_on_trailing_newline(ok_ty) + { + let local_snippet = snippet(cx, expr.span, ""); + span_lint_and_then( + cx, + READ_LINE_WITHOUT_TRIM, + span, + "calling `.parse()` without trimming the trailing newline character", + |diag| { + diag.span_note(call.span, "call to `.read_line()` here, \ + which leaves a trailing newline character in the buffer, \ + which in turn will cause `.parse()` to fail"); + + diag.span_suggestion( + expr.span, + "try", + format!("{local_snippet}.trim_end()"), + Applicability::MachineApplicable, + ); + } + ); + } + + // only consider the first use to prevent this scenario: + // ``` + // let mut s = String::new(); + // std::io::stdin().read_line(&mut s); + // s.pop(); + // let _x: i32 = s.parse().unwrap(); + // ``` + // this is actually fine, because the pop call removes the trailing newline. + ControlFlow::<(), ()>::Break(()) + }); + } +} diff --git a/clippy_lints/src/methods/repeat_once.rs b/clippy_lints/src/methods/repeat_once.rs index a345ec813ff5..bb4cdd2a6fa1 100644 --- a/clippy_lints/src/methods/repeat_once.rs +++ b/clippy_lints/src/methods/repeat_once.rs @@ -1,4 +1,4 @@ -use clippy_utils::consts::{constant_context, Constant}; +use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; use clippy_utils::ty::is_type_lang_item; @@ -14,7 +14,7 @@ pub(super) fn check<'tcx>( recv: &'tcx Expr<'_>, repeat_arg: &'tcx Expr<'_>, ) { - if constant_context(cx, cx.typeck_results()).expr(repeat_arg) == Some(Constant::Int(1)) { + if constant(cx, cx.typeck_results(), repeat_arg) == Some(Constant::Int(1)) { let ty = cx.typeck_results().expr_ty(recv).peel_refs(); if ty.is_str() { span_lint_and_sugg( diff --git a/clippy_lints/src/methods/seek_from_current.rs b/clippy_lints/src/methods/seek_from_current.rs index 361a3082f949..0828beedb728 100644 --- a/clippy_lints/src/methods/seek_from_current.rs +++ b/clippy_lints/src/methods/seek_from_current.rs @@ -3,10 +3,10 @@ use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; -use clippy_utils::{ - diagnostics::span_lint_and_sugg, get_trait_def_id, match_def_path, paths, source::snippet_with_applicability, - ty::implements_trait, -}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_with_applicability; +use clippy_utils::ty::implements_trait; +use clippy_utils::{get_trait_def_id, match_def_path, paths}; use super::SEEK_FROM_CURRENT; diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs index d00708e828ea..41986551da47 100644 --- a/clippy_lints/src/methods/str_splitn.rs +++ b/clippy_lints/src/methods/str_splitn.rs @@ -55,7 +55,7 @@ fn lint_needless(cx: &LateContext<'_>, method_name: &str, expr: &Expr<'_>, self_ NEEDLESS_SPLITN, expr.span, &format!("unnecessary use of `{r}splitn`"), - "try this", + "try", format!( "{}.{r}split({})", snippet_with_context(cx, self_arg.span, expr.span.ctxt(), "..", &mut app).0, @@ -110,7 +110,7 @@ fn check_manual_split_once( IterUsageKind::Nth(_) => return, }; - span_lint_and_sugg(cx, MANUAL_SPLIT_ONCE, usage.span, msg, "try this", sugg, app); + span_lint_and_sugg(cx, MANUAL_SPLIT_ONCE, usage.span, msg, "try", sugg, app); } /// checks for @@ -175,13 +175,13 @@ fn check_manual_split_once_indirect( let remove_msg = format!("remove the `{iter_ident}` usages"); diag.span_suggestion( first.span, - &remove_msg, + remove_msg.clone(), "", app, ); diag.span_suggestion( second.span, - &remove_msg, + remove_msg, "", app, ); @@ -289,7 +289,7 @@ fn parse_iter_usage<'tcx>( ) -> Option { let (kind, span) = match iter.next() { Some((_, Node::Expr(e))) if e.span.ctxt() == ctxt => { - let ExprKind::MethodCall(name, _, [args @ ..], _) = e.kind else { + let ExprKind::MethodCall(name, _, args, _) = e.kind else { return None; }; let did = cx.typeck_results().type_dependent_def_id(e.hir_id)?; @@ -316,7 +316,7 @@ fn parse_iter_usage<'tcx>( }; }, ("nth" | "skip", [idx_expr]) if cx.tcx.trait_of_item(did) == Some(iter_id) => { - if let Some((Constant::Int(idx), _)) = constant(cx, cx.typeck_results(), idx_expr) { + if let Some(Constant::Int(idx)) = constant(cx, cx.typeck_results(), idx_expr) { let span = if name.ident.as_str() == "nth" { e.span } else { diff --git a/clippy_lints/src/methods/string_extend_chars.rs b/clippy_lints/src/methods/string_extend_chars.rs index 2c20c6d752d7..c7885f689d75 100644 --- a/clippy_lints/src/methods/string_extend_chars.rs +++ b/clippy_lints/src/methods/string_extend_chars.rs @@ -34,7 +34,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr STRING_EXTEND_CHARS, expr.span, "calling `.extend(_.chars())`", - "try this", + "try", format!( "{}.push_str({ref_str}{})", snippet_with_applicability(cx, recv.span, "..", &mut applicability), diff --git a/clippy_lints/src/methods/suspicious_command_arg_space.rs b/clippy_lints/src/methods/suspicious_command_arg_space.rs index 73632c5a357d..bc8f01767641 100644 --- a/clippy_lints/src/methods/suspicious_command_arg_space.rs +++ b/clippy_lints/src/methods/suspicious_command_arg_space.rs @@ -1,11 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::paths; use clippy_utils::ty::match_type; -use rustc_ast as ast; use rustc_errors::{Applicability, Diagnostic}; -use rustc_hir as hir; use rustc_lint::LateContext; use rustc_span::Span; +use {rustc_ast as ast, rustc_hir as hir}; use super::SUSPICIOUS_COMMAND_ARG_SPACE; diff --git a/clippy_lints/src/methods/suspicious_to_owned.rs b/clippy_lints/src/methods/suspicious_to_owned.rs index e818f1892e51..9eb8d6e6e787 100644 --- a/clippy_lints/src/methods/suspicious_to_owned.rs +++ b/clippy_lints/src/methods/suspicious_to_owned.rs @@ -5,7 +5,8 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_middle::ty::{self, print::with_forced_trimmed_paths}; +use rustc_middle::ty::print::with_forced_trimmed_paths; +use rustc_middle::ty::{self}; use rustc_span::sym; use super::SUSPICIOUS_TO_OWNED; diff --git a/clippy_lints/src/methods/type_id_on_box.rs b/clippy_lints/src/methods/type_id_on_box.rs new file mode 100644 index 000000000000..35137c97101e --- /dev/null +++ b/clippy_lints/src/methods/type_id_on_box.rs @@ -0,0 +1,62 @@ +use crate::methods::TYPE_ID_ON_BOX; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::source::snippet; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty::adjustment::{Adjust, Adjustment}; +use rustc_middle::ty::{self, ExistentialPredicate, Ty}; +use rustc_span::{sym, Span}; + +fn is_dyn_any(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { + if let ty::Dynamic(preds, ..) = ty.kind() { + preds.iter().any(|p| match p.skip_binder() { + ExistentialPredicate::Trait(tr) => cx.tcx.is_diagnostic_item(sym::Any, tr.def_id), + _ => false, + }) + } else { + false + } +} + +pub(super) fn check(cx: &LateContext<'_>, receiver: &Expr<'_>, call_span: Span) { + let recv_adjusts = cx.typeck_results().expr_adjustments(receiver); + + if let Some(Adjustment { target: recv_ty, .. }) = recv_adjusts.last() + && let ty::Ref(_, ty, _) = recv_ty.kind() + && let ty::Adt(adt, substs) = ty.kind() + && adt.is_box() + && is_dyn_any(cx, substs.type_at(0)) + { + span_lint_and_then( + cx, + TYPE_ID_ON_BOX, + call_span, + "calling `.type_id()` on a `Box`", + |diag| { + let derefs = recv_adjusts + .iter() + .filter(|adj| matches!(adj.kind, Adjust::Deref(None))) + .count(); + + let mut sugg = "*".repeat(derefs + 1); + sugg += &snippet(cx, receiver.span, ""); + + diag.note( + "this returns the type id of the literal type `Box` instead of the \ + type id of the boxed value, which is most likely not what you want" + ) + .note( + "if this is intentional, use `TypeId::of::>()` instead, \ + which makes it more clear" + ) + .span_suggestion( + receiver.span, + "consider dereferencing first", + format!("({sugg})"), + Applicability::MaybeIncorrect, + ); + }, + ); + } +} diff --git a/clippy_lints/src/methods/uninit_assumed_init.rs b/clippy_lints/src/methods/uninit_assumed_init.rs index a1c6294737cf..bc9c518dbcf0 100644 --- a/clippy_lints/src/methods/uninit_assumed_init.rs +++ b/clippy_lints/src/methods/uninit_assumed_init.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint; -use clippy_utils::{is_path_diagnostic_item, ty::is_uninit_value_valid_for_ty}; +use clippy_utils::is_path_diagnostic_item; +use clippy_utils::ty::is_uninit_value_valid_for_ty; use if_chain::if_chain; use rustc_hir as hir; use rustc_lint::LateContext; diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index 1cef6226ad4f..cc64a2e79487 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -11,8 +11,7 @@ use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::sym; -use super::UNNECESSARY_FILTER_MAP; -use super::UNNECESSARY_FIND_MAP; +use super::{UNNECESSARY_FILTER_MAP, UNNECESSARY_FIND_MAP}; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, arg: &'tcx hir::Expr<'tcx>, name: &str) { if !is_trait_method(cx, expr, sym::Iterator) { diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs index aa87dead38f0..33a8a5bf3f16 100644 --- a/clippy_lints/src/methods/unnecessary_fold.rs +++ b/clippy_lints/src/methods/unnecessary_fold.rs @@ -7,10 +7,161 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::PatKind; use rustc_lint::LateContext; -use rustc_span::{source_map::Span, sym}; +use rustc_middle::ty; +use rustc_span::source_map::Span; +use rustc_span::sym; use super::UNNECESSARY_FOLD; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 69e892e3a (get rid of unnecessary function pointer) +/// Do we need to suggest turbofish when suggesting a replacement method? +/// Changing `fold` to `sum` needs it sometimes when the return type can't be +/// inferred. This checks for some common cases where it can be safely omitted +fn needs_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { +<<<<<<< HEAD +======= +/// No turbofish needed in any case. +fn no_turbofish(_: &LateContext<'_>, _: &hir::Expr<'_>) -> bool { + false +} + +/// Turbofish (`::`) may be needed, but can be omitted if we are certain +/// that the type can be inferred from usage. +fn turbofish_if_not_inferred(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { +>>>>>>> c9daec258 ([`unnecessary_fold`]: suggest turbofish if necessary) +======= +>>>>>>> 69e892e3a (get rid of unnecessary function pointer) + let parent = cx.tcx.hir().get_parent(expr.hir_id); + + // some common cases where turbofish isn't needed: + // - assigned to a local variable with a type annotation + if let hir::Node::Local(local) = parent + && local.ty.is_some() + { + return false; + } + + // - part of a function call argument, can be inferred from the function signature (provided that + // the parameter is not a generic type parameter) + if let hir::Node::Expr(parent_expr) = parent + && let hir::ExprKind::Call(recv, args) = parent_expr.kind + && let hir::ExprKind::Path(ref qpath) = recv.kind + && let Some(fn_def_id) = cx.qpath_res(qpath, recv.hir_id).opt_def_id() + && let fn_sig = cx.tcx.fn_sig(fn_def_id).skip_binder().skip_binder() + && let Some(arg_pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id) + && let Some(ty) = fn_sig.inputs().get(arg_pos) + && !matches!(ty.kind(), ty::Param(_)) + { + return false; + } + + // if it's neither of those, stay on the safe side and suggest turbofish, + // even if it could work! + true +} + +#[derive(Copy, Clone)] +struct Replacement { + method_name: &'static str, + has_args: bool, +<<<<<<< HEAD +<<<<<<< HEAD + has_generic_return: bool, +} + +fn check_fold_with_op( + cx: &LateContext<'_>, + expr: &hir::Expr<'_>, + acc: &hir::Expr<'_>, + fold_span: Span, + op: hir::BinOpKind, + replacement: Replacement, +) { + if_chain! { + // Extract the body of the closure passed to fold + if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = acc.kind; + let closure_body = cx.tcx.hir().body(body); + let closure_expr = peel_blocks(closure_body.value); + + // Check if the closure body is of the form `acc some_expr(x)` + if let hir::ExprKind::Binary(ref bin_op, left_expr, right_expr) = closure_expr.kind; + if bin_op.node == op; + + // Extract the names of the two arguments to the closure + if let [param_a, param_b] = closure_body.params; + if let PatKind::Binding(_, first_arg_id, ..) = strip_pat_refs(param_a.pat).kind; + if let PatKind::Binding(_, second_arg_id, second_arg_ident, _) = strip_pat_refs(param_b.pat).kind; + + if path_to_local_id(left_expr, first_arg_id); + if replacement.has_args || path_to_local_id(right_expr, second_arg_id); + + then { + let mut applicability = Applicability::MachineApplicable; + + let turbofish = if replacement.has_generic_return { + format!("::<{}>", cx.typeck_results().expr_ty_adjusted(right_expr).peel_refs()) + } else { + String::new() + }; + + let sugg = if replacement.has_args { + format!( + "{method}{turbofish}(|{second_arg_ident}| {r})", + method = replacement.method_name, + r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability), + ) + } else { + format!( + "{method}{turbofish}()", + method = replacement.method_name, + ) + }; + + span_lint_and_sugg( + cx, + UNNECESSARY_FOLD, + fold_span.with_hi(expr.span.hi()), + // TODO #2371 don't suggest e.g., .any(|x| f(x)) if we can suggest .any(f) + "this `.fold` can be written more succinctly using another method", + "try", + sugg, + applicability, + ); +<<<<<<< HEAD +======= + requires_turbofish: fn(&LateContext<'_>, &hir::Expr<'_>) -> bool, +} +impl Replacement { + /// `any(f)`, `all(f)` + pub fn non_generic(method_name: &'static str) -> Self { + Self { + method_name, + has_args: true, + requires_turbofish: no_turbofish, + } + } + + /// `sum::()`, `product::()` + pub fn generic(method_name: &'static str) -> Self { + Self { + method_name, + has_args: false, + requires_turbofish: turbofish_if_not_inferred, +>>>>>>> c9daec258 ([`unnecessary_fold`]: suggest turbofish if necessary) + } + } +======= + has_generic_return: bool, +>>>>>>> 69e892e3a (get rid of unnecessary function pointer) +======= + } + } +>>>>>>> d102e2296 (move check_fold_with_op function out) +} + pub(super) fn check( cx: &LateContext<'_>, expr: &hir::Expr<'_>, @@ -18,14 +169,16 @@ pub(super) fn check( acc: &hir::Expr<'_>, fold_span: Span, ) { +<<<<<<< HEAD +<<<<<<< HEAD +======= fn check_fold_with_op( cx: &LateContext<'_>, expr: &hir::Expr<'_>, acc: &hir::Expr<'_>, fold_span: Span, op: hir::BinOpKind, - replacement_method_name: &str, - replacement_has_args: bool, + replacement: Replacement, ) { if_chain! { // Extract the body of the closure passed to fold @@ -43,18 +196,27 @@ pub(super) fn check( if let PatKind::Binding(_, second_arg_id, second_arg_ident, _) = strip_pat_refs(param_b.pat).kind; if path_to_local_id(left_expr, first_arg_id); - if replacement_has_args || path_to_local_id(right_expr, second_arg_id); + if replacement.has_args || path_to_local_id(right_expr, second_arg_id); then { let mut applicability = Applicability::MachineApplicable; - let sugg = if replacement_has_args { + + let turbofish = if replacement.has_generic_return { + format!("::<{}>", cx.typeck_results().expr_ty_adjusted(right_expr).peel_refs()) + } else { + String::new() + }; + + let sugg = if replacement.has_args { format!( - "{replacement_method_name}(|{second_arg_ident}| {r})", + "{method}{turbofish}(|{second_arg_ident}| {r})", + method = replacement.method_name, r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability), ) } else { format!( - "{replacement_method_name}()", + "{method}{turbofish}()", + method = replacement.method_name, ) }; @@ -72,6 +234,9 @@ pub(super) fn check( } } +>>>>>>> c9daec258 ([`unnecessary_fold`]: suggest turbofish if necessary) +======= +>>>>>>> d102e2296 (move check_fold_with_op function out) // Check that this is a call to Iterator::fold rather than just some function called fold if !is_trait_method(cx, expr, sym::Iterator) { return; @@ -80,11 +245,99 @@ pub(super) fn check( // Check if the first argument to .fold is a suitable literal if let hir::ExprKind::Lit(ref lit) = init.kind { match lit.node { - ast::LitKind::Bool(false) => check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Or, "any", true), - ast::LitKind::Bool(true) => check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::And, "all", true), - ast::LitKind::Int(0, _) => check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Add, "sum", false), + ast::LitKind::Bool(false) => { + check_fold_with_op( + cx, + expr, + acc, + fold_span, + hir::BinOpKind::Or, +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 69e892e3a (get rid of unnecessary function pointer) + Replacement { + has_args: true, + has_generic_return: false, + method_name: "any", + }, +<<<<<<< HEAD +======= + Replacement::non_generic("any"), +>>>>>>> c9daec258 ([`unnecessary_fold`]: suggest turbofish if necessary) +======= +>>>>>>> 69e892e3a (get rid of unnecessary function pointer) + ); + }, + ast::LitKind::Bool(true) => { + check_fold_with_op( + cx, + expr, + acc, + fold_span, + hir::BinOpKind::And, +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 69e892e3a (get rid of unnecessary function pointer) + Replacement { + has_args: true, + has_generic_return: false, + method_name: "all", + }, +<<<<<<< HEAD +======= + Replacement::non_generic("all"), +>>>>>>> c9daec258 ([`unnecessary_fold`]: suggest turbofish if necessary) +======= +>>>>>>> 69e892e3a (get rid of unnecessary function pointer) + ); + }, + ast::LitKind::Int(0, _) => check_fold_with_op( + cx, + expr, + acc, + fold_span, + hir::BinOpKind::Add, +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 69e892e3a (get rid of unnecessary function pointer) + Replacement { + has_args: false, + has_generic_return: needs_turbofish(cx, expr), + method_name: "sum", + }, +<<<<<<< HEAD +======= + Replacement::generic("sum"), +>>>>>>> c9daec258 ([`unnecessary_fold`]: suggest turbofish if necessary) +======= +>>>>>>> 69e892e3a (get rid of unnecessary function pointer) + ), ast::LitKind::Int(1, _) => { - check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Mul, "product", false); + check_fold_with_op( + cx, + expr, + acc, + fold_span, + hir::BinOpKind::Mul, +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 69e892e3a (get rid of unnecessary function pointer) + Replacement { + has_args: false, + has_generic_return: needs_turbofish(cx, expr), + method_name: "product", + }, +<<<<<<< HEAD +======= + Replacement::generic("product"), +>>>>>>> c9daec258 ([`unnecessary_fold`]: suggest turbofish if necessary) +======= +>>>>>>> 69e892e3a (get rid of unnecessary function pointer) + ); }, _ => (), } diff --git a/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/clippy_lints/src/methods/unnecessary_iter_cloned.rs index 52a4ff7d1ae4..0c72c13a3caa 100644 --- a/clippy_lints/src/methods/unnecessary_iter_cloned.rs +++ b/clippy_lints/src/methods/unnecessary_iter_cloned.rs @@ -5,7 +5,8 @@ use clippy_utils::source::snippet_opt; use clippy_utils::ty::{get_iterator_item_ty, implements_trait}; use clippy_utils::{fn_def_id, get_parent_expr}; use rustc_errors::Applicability; -use rustc_hir::{def_id::DefId, Expr, ExprKind}; +use rustc_hir::def_id::DefId; +use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; use rustc_span::{sym, Symbol}; diff --git a/clippy_lints/src/methods/unnecessary_join.rs b/clippy_lints/src/methods/unnecessary_join.rs index 087e1e4343b7..d0c62fb56dc2 100644 --- a/clippy_lints/src/methods/unnecessary_join.rs +++ b/clippy_lints/src/methods/unnecessary_join.rs @@ -1,4 +1,5 @@ -use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::ty::is_type_lang_item; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, LangItem}; diff --git a/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/clippy_lints/src/methods/unnecessary_literal_unwrap.rs new file mode 100644 index 000000000000..915b33917d14 --- /dev/null +++ b/clippy_lints/src/methods/unnecessary_literal_unwrap.rs @@ -0,0 +1,241 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::{diagnostics::span_lint_and_then, is_res_lang_ctor, last_path_segment, path_res, MaybePath}; +======= +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::{is_res_lang_ctor, last_path_segment, path_res, MaybePath}; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::UNNECESSARY_LITERAL_UNWRAP; + +fn get_ty_from_args<'a>(args: Option<&'a [hir::GenericArg<'a>]>, index: usize) -> Option<&'a hir::Ty<'a>> { + let args = args?; + + if args.len() <= index { + return None; + } + + match args[index] { + hir::GenericArg::Type(ty) => match ty.kind { + hir::TyKind::Infer => None, + _ => Some(ty), + }, + _ => None, + } +} + +pub(super) fn check( + cx: &LateContext<'_>, + expr: &hir::Expr<'_>, + recv: &hir::Expr<'_>, + method: &str, + args: &[hir::Expr<'_>], +) { + let init = clippy_utils::expr_or_init(cx, recv); + if init.span.from_expansion() { + // don't lint if the receiver or binding initializer comes from a macro + // (e.g. `let x = option_env!(..); x.unwrap()`) + return; + } + + let (constructor, call_args, ty) = if let hir::ExprKind::Call(call, call_args) = init.kind { + let Some(qpath) = call.qpath_opt() else { return }; + + let args = last_path_segment(qpath).args.map(|args| args.args); + let res = cx.qpath_res(qpath, call.hir_id()); + + if is_res_lang_ctor(cx, res, hir::LangItem::OptionSome) { + ("Some", call_args, get_ty_from_args(args, 0)) + } else if is_res_lang_ctor(cx, res, hir::LangItem::ResultOk) { + ("Ok", call_args, get_ty_from_args(args, 0)) + } else if is_res_lang_ctor(cx, res, hir::LangItem::ResultErr) { + ("Err", call_args, get_ty_from_args(args, 1)) + } else { + return; + } + } else if is_res_lang_ctor(cx, path_res(cx, init), hir::LangItem::OptionNone) { + let call_args: &[hir::Expr<'_>] = &[]; + ("None", call_args, None) + } else { + return; + }; + + let help_message = format!("used `{method}()` on `{constructor}` value"); + let suggestion_message = format!("remove the `{constructor}` and `{method}()`"); + + span_lint_and_then(cx, UNNECESSARY_LITERAL_UNWRAP, expr.span, &help_message, |diag| { + let suggestions = match (constructor, method, ty) { + ("None", "unwrap", _) => Some(vec![(expr.span, "panic!()".to_string())]), + ("None", "expect", _) => Some(vec![ + (expr.span.with_hi(args[0].span.lo()), "panic!(".to_string()), + (expr.span.with_lo(args[0].span.hi()), ")".to_string()), + ]), + ("Some" | "Ok", "unwrap_unchecked", _) | ("Err", "unwrap_err_unchecked", _) => { + let mut suggs = vec![ + (recv.span.with_hi(call_args[0].span.lo()), String::new()), + (expr.span.with_lo(call_args[0].span.hi()), String::new()), + ]; + // try to also remove the unsafe block if present + if let hir::Node::Block(block) = cx.tcx.hir().get_parent(expr.hir_id) + && let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = block.rules + { + suggs.extend([ + (block.span.shrink_to_lo().to(expr.span.shrink_to_lo()), String::new()), + (expr.span.shrink_to_hi().to(block.span.shrink_to_hi()), String::new()) + ]); + } + Some(suggs) + }, + (_, _, Some(_)) => None, + ("Ok", "unwrap_err", None) | ("Err", "unwrap", None) => Some(vec![ + ( + recv.span.with_hi(call_args[0].span.lo()), + "panic!(\"{:?}\", ".to_string(), + ), + (expr.span.with_lo(call_args[0].span.hi()), ")".to_string()), + ]), + ("Ok", "expect_err", None) | ("Err", "expect", None) => Some(vec![ + ( + recv.span.with_hi(call_args[0].span.lo()), + "panic!(\"{1}: {:?}\", ".to_string(), + ), + (call_args[0].span.with_lo(args[0].span.lo()), ", ".to_string()), + ]), + (_, _, None) => Some(vec![ + (recv.span.with_hi(call_args[0].span.lo()), String::new()), + (expr.span.with_lo(call_args[0].span.hi()), String::new()), + ]), + }; + + match (init.span == recv.span, suggestions) { + (true, Some(suggestions)) => { + diag.multipart_suggestion(suggestion_message, suggestions, Applicability::MachineApplicable); + }, + _ => { + diag.span_help(init.span, suggestion_message); + }, + } + }); +======= +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::ty::is_type_diagnostic_item; +======= +use clippy_utils::{diagnostics::span_lint_and_help, is_res_lang_ctor, path_res}; +>>>>>>> 0b1bb5fbf (Implement the lint) +======= +use clippy_utils::{diagnostics::span_lint_and_then, is_res_lang_ctor, path_res}; +======= +use clippy_utils::{diagnostics::span_lint_and_then, is_res_lang_ctor, last_path_segment, path_res, MaybePath}; +>>>>>>> 6e4c5561b (Preserve type annotations when present) +use rustc_errors::Applicability; +>>>>>>> daf619748 (Implement the suggestion) +use rustc_hir as hir; +use rustc_lint::LateContext; + +use super::UNNECESSARY_LITERAL_UNWRAP; + +fn get_ty_from_args<'a>(args: Option<&'a [hir::GenericArg<'a>]>, index: usize) -> Option<&'a hir::Ty<'a>> { + let args = args?; + + if args.len() <= index { + return None; + } + + match args[index] { + hir::GenericArg::Type(ty) => match ty.kind { + hir::TyKind::Infer => None, + _ => Some(ty), + }, + _ => None, + } +} + +pub(super) fn check( + cx: &LateContext<'_>, + expr: &hir::Expr<'_>, + recv: &hir::Expr<'_>, + method: &str, + args: &[hir::Expr<'_>], +) { + let init = clippy_utils::expr_or_init(cx, recv); + + let (constructor, call_args, ty) = if let hir::ExprKind::Call(call, call_args) = init.kind { + let Some(qpath) = call.qpath_opt() else { return }; + + let args = last_path_segment(qpath).args.map(|args| args.args); + let res = cx.qpath_res(qpath, call.hir_id()); + + if is_res_lang_ctor(cx, res, hir::LangItem::OptionSome) { + ("Some", call_args, get_ty_from_args(args, 0)) + } else if is_res_lang_ctor(cx, res, hir::LangItem::ResultOk) { + ("Ok", call_args, get_ty_from_args(args, 0)) + } else if is_res_lang_ctor(cx, res, hir::LangItem::ResultErr) { + ("Err", call_args, get_ty_from_args(args, 1)) + } else { + return; + } + } else if is_res_lang_ctor(cx, path_res(cx, init), hir::LangItem::OptionNone) { + let call_args: &[hir::Expr<'_>] = &[]; + ("None", call_args, None) + } else { + return; + }; + + let help_message = format!("used `{method}()` on `{constructor}` value"); + let suggestion_message = format!("remove the `{constructor}` and `{method}()`"); + + span_lint_and_then(cx, UNNECESSARY_LITERAL_UNWRAP, expr.span, &help_message, |diag| { + let suggestions = match (constructor, method, ty) { + ("None", "unwrap", _) => Some(vec![(expr.span, "panic!()".to_string())]), + ("None", "expect", _) => Some(vec![ + (expr.span.with_hi(args[0].span.lo()), "panic!(".to_string()), + (expr.span.with_lo(args[0].span.hi()), ")".to_string()), + ]), + (_, _, Some(_)) => None, + ("Ok", "unwrap_err", None) | ("Err", "unwrap", None) => Some(vec![ + ( + recv.span.with_hi(call_args[0].span.lo()), + "panic!(\"{:?}\", ".to_string(), + ), + (expr.span.with_lo(call_args[0].span.hi()), ")".to_string()), + ]), + ("Ok", "expect_err", None) | ("Err", "expect", None) => Some(vec![ + ( + recv.span.with_hi(call_args[0].span.lo()), + "panic!(\"{1}: {:?}\", ".to_string(), + ), + (call_args[0].span.with_lo(args[0].span.lo()), ", ".to_string()), + ]), + (_, _, None) => Some(vec![ + (recv.span.with_hi(call_args[0].span.lo()), String::new()), + (expr.span.with_lo(call_args[0].span.hi()), String::new()), + ]), + }; + +<<<<<<< HEAD + diag.multipart_suggestion(suggestion_message, suggestions, Applicability::MachineApplicable); + }); + } else { + span_lint_and_then(cx, UNNECESSARY_LITERAL_UNWRAP, expr.span, &help_message, |diag| { + diag.span_help(init.span, suggestion_message); + }); + } +>>>>>>> e707447a8 (Boilerplate for the new lint) +======= + match (init.span == recv.span, suggestions) { + (true, Some(suggestions)) => { + diag.multipart_suggestion(suggestion_message, suggestions, Applicability::MachineApplicable); + }, + _ => { + diag.span_help(init.span, suggestion_message); + }, + } + }); +>>>>>>> 6e4c5561b (Preserve type annotations when present) +} diff --git a/clippy_lints/src/methods/unnecessary_sort_by.rs b/clippy_lints/src/methods/unnecessary_sort_by.rs index 67618f7038ad..54b76bd04fe0 100644 --- a/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -6,7 +6,8 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Closure, Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath}; use rustc_lint::LateContext; -use rustc_middle::ty::{self, subst::GenericArgKind}; +use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::{self}; use rustc_span::sym; use rustc_span::symbol::Ident; use std::iter; diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs index 4c4c003ca469..5c7d21ca663c 100644 --- a/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -7,16 +7,18 @@ use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, peel_mid use clippy_utils::visitors::find_all_ret_expressions; use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, return_ty}; use rustc_errors::Applicability; -use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, Node}; +use rustc_hir::def_id::DefId; +use rustc_hir::{BorrowKind, Expr, ExprKind, ItemKind, Node}; use rustc_hir_typeck::{FnCtxt, Inherited}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, Clause, EarlyBinder, ParamTy, PredicateKind, ProjectionPredicate, TraitPredicate, Ty}; +use rustc_middle::ty::{self, ClauseKind, EarlyBinder, ParamTy, ProjectionPredicate, TraitPredicate, Ty}; use rustc_span::{sym, Symbol}; -use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause}; +use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; +use rustc_trait_selection::traits::{Obligation, ObligationCause}; use super::UNNECESSARY_TO_OWNED; @@ -144,6 +146,11 @@ fn check_addr_of_expr( if let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref); if implements_trait(cx, receiver_ty, deref_trait_id, &[]); if cx.get_associated_type(receiver_ty, deref_trait_id, "Target") == Some(target_ty); + // Make sure that it's actually calling the right `.to_string()`, (#10033) + // *or* this is a `Cow::into_owned()` call (which would be the wrong into_owned receiver (str != Cow) + // but that's ok for Cow::into_owned specifically) + if cx.typeck_results().expr_ty_adjusted(receiver).peel_refs() == target_ty + || is_cow_into_owned(cx, method_name, method_def_id); then { if n_receiver_refs > 0 { span_lint_and_sugg( @@ -265,7 +272,7 @@ fn check_other_call_arg<'tcx>( if let Some((n_refs, receiver_ty)) = if n_refs > 0 || is_copy(cx, receiver_ty) { Some((n_refs, receiver_ty)) } else if trait_predicate.def_id() != deref_trait_id { - Some((1, cx.tcx.mk_ref( + Some((1, Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, ty::TypeAndMut { ty: receiver_ty, @@ -345,12 +352,12 @@ fn get_input_traits_and_projections<'tcx>( let mut projection_predicates = Vec::new(); for predicate in cx.tcx.param_env(callee_def_id).caller_bounds() { match predicate.kind().skip_binder() { - PredicateKind::Clause(Clause::Trait(trait_predicate)) => { + ClauseKind::Trait(trait_predicate) => { if trait_predicate.trait_ref.self_ty() == input { trait_predicates.push(trait_predicate); } }, - PredicateKind::Clause(Clause::Projection(projection_predicate)) => { + ClauseKind::Projection(projection_predicate) => { if projection_predicate.projection_ty.self_ty() == input { projection_predicates.push(projection_predicate); } @@ -385,6 +392,9 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< Node::Expr(parent_expr) => { if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr) { + // FIXME: the `subst_identity()` below seems incorrect, since we eventually + // call `tcx.try_subst_and_normalize_erasing_regions` further down + // (i.e., we are explicitly not in the identity context). let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder(); if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id) && let Some(param_ty) = fn_sig.inputs().get(arg_index) @@ -404,7 +414,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< let mut trait_predicates = cx.tcx.param_env(callee_def_id) .caller_bounds().iter().filter(|predicate| { - if let PredicateKind::Clause(Clause::Trait(trait_predicate)) + if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() && trait_predicate.trait_ref.self_ty() == *param_ty { @@ -425,7 +435,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< })); if trait_predicates.any(|predicate| { - let predicate = EarlyBinder(predicate).subst(cx.tcx, new_subst); + let predicate = EarlyBinder::bind(predicate).subst(cx.tcx, new_subst); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); !cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation) }) { @@ -435,7 +445,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< let output_ty = fn_sig.output(); if output_ty.contains(*param_ty) { if let Ok(new_ty) = cx.tcx.try_subst_and_normalize_erasing_regions( - new_subst, cx.param_env, output_ty) { + new_subst, cx.param_env, EarlyBinder::bind(output_ty)) { expr = parent_expr; ty = new_ty; continue; diff --git a/clippy_lints/src/methods/unwrap_or_else_default.rs b/clippy_lints/src/methods/unwrap_or_else_default.rs index 045f739e64de..474a33b67e1c 100644 --- a/clippy_lints/src/methods/unwrap_or_else_default.rs +++ b/clippy_lints/src/methods/unwrap_or_else_default.rs @@ -1,10 +1,10 @@ //! Lint for `some_result_or_option.unwrap_or_else(Default::default)` use super::UNWRAP_OR_ELSE_DEFAULT; -use clippy_utils::{ - diagnostics::span_lint_and_sugg, is_default_equivalent_call, source::snippet_with_applicability, - ty::is_type_diagnostic_item, -}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_default_equivalent_call; +use clippy_utils::source::snippet_with_applicability; +use clippy_utils::ty::is_type_diagnostic_item; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir as hir; diff --git a/clippy_lints/src/methods/useless_asref.rs b/clippy_lints/src/methods/useless_asref.rs index c1139d84e2f4..b5f810eddf4a 100644 --- a/clippy_lints/src/methods/useless_asref.rs +++ b/clippy_lints/src/methods/useless_asref.rs @@ -37,7 +37,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, USELESS_ASREF, expr.span, &format!("this call to `{call_name}` does nothing"), - "try this", + "try", snippet_with_applicability(cx, recvr.span, "..", &mut applicability).to_string(), applicability, ); diff --git a/clippy_lints/src/min_ident_chars.rs b/clippy_lints/src/min_ident_chars.rs new file mode 100644 index 000000000000..1a79b61ed498 --- /dev/null +++ b/clippy_lints/src/min_ident_chars.rs @@ -0,0 +1,275 @@ +use clippy_utils::diagnostics::span_lint; +use clippy_utils::is_from_proc_macro; +use rustc_data_structures::fx::FxHashSet; +<<<<<<< HEAD +use rustc_hir::{ + def::{DefKind, Res}, + intravisit::{walk_item, Visitor}, +<<<<<<< HEAD +<<<<<<< HEAD + GenericParamKind, HirId, Item, ItemKind, ItemLocalId, Node, Pat, PatKind, +======= + GenericParamKind, HirId, Item, ItemKind, ItemLocalId, Node, +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + GenericParamKind, HirId, Item, ItemKind, ItemLocalId, Node, Pat, PatKind, +>>>>>>> 243943ff5 (make it work for locals as well) +}; +======= +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::intravisit::{walk_item, Visitor}; +use rustc_hir::{GenericParamKind, HirId, Item, ItemKind, ItemLocalId, Node, Pat, PatKind}; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +<<<<<<< HEAD +<<<<<<< HEAD +use rustc_span::Span; +======= +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +use rustc_span::Span; +>>>>>>> 95d1bff22 (add to tests and configuration) +use std::borrow::Cow; + +declare_clippy_lint! { + /// ### What it does + /// Checks for idents which comprise of a single letter. + /// + /// Note: This lint can be very noisy when enabled; it may be desirable to only enable it + /// temporarily. + /// + /// ### Why is this bad? + /// In many cases it's not, but at times it can severely hinder readability. Some codebases may + /// wish to disallow this to improve readability. + /// + /// ### Example + /// ```rust,ignore + /// for m in movies { + /// let title = m.t; + /// } + /// ``` + /// Use instead: + /// ```rust,ignore + /// for movie in movies { + /// let title = movie.title; + /// } + /// ``` +<<<<<<< HEAD +<<<<<<< HEAD +======= + /// ``` +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +>>>>>>> 29c1c6e10 (refactor and add link to issue) + #[clippy::version = "1.72.0"] + pub MIN_IDENT_CHARS, + restriction, + "disallows idents that are too short" +} +impl_lint_pass!(MinIdentChars => [MIN_IDENT_CHARS]); + +#[derive(Clone)] +pub struct MinIdentChars { + pub allowed_idents_below_min_chars: FxHashSet, + pub min_ident_chars_threshold: u64, +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 29c1c6e10 (refactor and add link to issue) +impl MinIdentChars { + #[expect(clippy::cast_possible_truncation)] + fn is_ident_too_short(&self, cx: &LateContext<'_>, str: &str, span: Span) -> bool { + !in_external_macro(cx.sess(), span) + && str.len() <= self.min_ident_chars_threshold as usize + && !str.starts_with('_') + && !str.is_empty() + && self.allowed_idents_below_min_chars.get(&str.to_owned()).is_none() + } +} + +<<<<<<< HEAD +======= +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +>>>>>>> 29c1c6e10 (refactor and add link to issue) +impl LateLintPass<'_> for MinIdentChars { + fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { + if self.min_ident_chars_threshold == 0 { + return; + } + + walk_item(&mut IdentVisitor { conf: self, cx }, item); + } +<<<<<<< HEAD +<<<<<<< HEAD + + // This is necessary as `Node::Pat`s are not visited in `visit_id`. :/ + fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) { + if let PatKind::Binding(_, _, ident, ..) = pat.kind + && let str = ident.as_str() + && self.is_ident_too_short(cx, str, ident.span) + { + emit_min_ident_chars(self, cx, str, ident.span); + } + } +======= +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + + // This is necessary as `Node::Pat`s are not visited in `visit_id`. :/ + fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) { + if let PatKind::Binding(_, _, ident, ..) = pat.kind + && let str = ident.as_str() + && self.is_ident_too_short(cx, str, ident.span) + { + emit_min_ident_chars(self, cx, str, ident.span); + } + } +>>>>>>> 243943ff5 (make it work for locals as well) +} + +struct IdentVisitor<'cx, 'tcx> { + conf: &'cx MinIdentChars, + cx: &'cx LateContext<'tcx>, +} + +<<<<<<< HEAD +<<<<<<< HEAD +impl Visitor<'_> for IdentVisitor<'_, '_> { + fn visit_id(&mut self, hir_id: HirId) { + let Self { conf, cx } = *self; + // FIXME(#112534) Reimplementation of `find`, as it uses indexing, which can (and will in + // async functions, or really anything async) panic. This should probably be fixed on the + // rustc side, this is just a temporary workaround. +======= +#[expect(clippy::cast_possible_truncation)] +======= +>>>>>>> 243943ff5 (make it work for locals as well) +impl Visitor<'_> for IdentVisitor<'_, '_> { + fn visit_id(&mut self, hir_id: HirId) { + let Self { conf, cx } = *self; +<<<<<<< HEAD + // Reimplementation of `find`, as it uses indexing, which can (and will in async functions) panic. + // This should probably be fixed on the rustc side, this is just a temporary workaround. + // FIXME: Remove me if/when this is fixed in rustc +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + // FIXME(#112534) Reimplementation of `find`, as it uses indexing, which can (and will in + // async functions, or really anything async) panic. This should probably be fixed on the + // rustc side, this is just a temporary workaround. +>>>>>>> 29c1c6e10 (refactor and add link to issue) + let node = if hir_id.local_id == ItemLocalId::from_u32(0) { + // In this case, we can just use `find`, `Owner`'s `node` field is private anyway so we can't + // reimplement it even if we wanted to + cx.tcx.hir().find(hir_id) + } else { + let Some(owner) = cx.tcx.hir_owner_nodes(hir_id.owner).as_owner() else { + return; + }; + owner.nodes.get(hir_id.local_id).copied().flatten().map(|p| p.node) + }; + let Some(node) = node else { + return; + }; + let Some(ident) = node.ident() else { + return; + }; + + let str = ident.as_str(); +<<<<<<< HEAD +<<<<<<< HEAD + if conf.is_ident_too_short(cx, str, ident.span) { +======= + if !in_external_macro(cx.sess(), ident.span) + && str.len() <= conf.min_ident_chars_threshold as usize + && !str.starts_with('_') + && !str.is_empty() + && conf.allowed_idents_below_min_chars.get(&str.to_owned()).is_none() + { +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + if conf.is_ident_too_short(cx, str, ident.span) { +>>>>>>> 29c1c6e10 (refactor and add link to issue) + if let Node::Item(item) = node && let ItemKind::Use(..) = item.kind { + return; + } + // `struct Awa(T)` + // ^ + if let Node::PathSegment(path) = node { + if let Res::Def(def_kind, ..) = path.res && let DefKind::TyParam = def_kind { + return; + } + if matches!(path.res, Res::PrimTy(..)) || path.res.opt_def_id().is_some_and(|def_id| !def_id.is_local()) + { + return; + } + } + // `struct Awa(T)` + // ^ + if let Node::GenericParam(generic_param) = node + && let GenericParamKind::Type { .. } = generic_param.kind + { + return; + } + + if is_from_proc_macro(cx, &ident) { + return; + } + +<<<<<<< HEAD +<<<<<<< HEAD + emit_min_ident_chars(conf, cx, str, ident.span); + } + } +} + +fn emit_min_ident_chars(conf: &MinIdentChars, cx: &impl LintContext, ident: &str, span: Span) { + let help = if conf.min_ident_chars_threshold == 1 { + Cow::Borrowed("this ident consists of a single char") + } else { + Cow::Owned(format!( + "this ident is too short ({} <= {})", + ident.len(), + conf.min_ident_chars_threshold, + )) + }; + span_lint(cx, MIN_IDENT_CHARS, span, &help); +} +======= + let help = if conf.min_ident_chars_threshold == 1 { + Cow::Borrowed("this ident consists of a single char") + } else { + Cow::Owned(format!( + "this ident is too short ({} <= {})", + str.len(), + conf.min_ident_chars_threshold, + )) + }; + span_lint(cx, MIN_IDENT_CHARS, ident.span, &help); + } + } +} +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + emit_min_ident_chars(conf, cx, str, ident.span); + } + } +} + +fn emit_min_ident_chars(conf: &MinIdentChars, cx: &impl LintContext, ident: &str, span: Span) { + let help = if conf.min_ident_chars_threshold == 1 { + Cow::Borrowed("this ident consists of a single char") + } else { + Cow::Owned(format!( + "this ident is too short ({} <= {})", + ident.len(), + conf.min_ident_chars_threshold, + )) + }; + span_lint(cx, MIN_IDENT_CHARS, span, &help); +} +>>>>>>> 95d1bff22 (add to tests and configuration) diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index 4f967755bfa1..e0904f17b8de 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -66,7 +66,7 @@ enum MinMax { Max, } -fn min_max<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(MinMax, Constant, &'a Expr<'a>)> { +fn min_max<'a, 'tcx>(cx: &LateContext<'tcx>, expr: &'a Expr<'a>) -> Option<(MinMax, Constant<'tcx>, &'a Expr<'a>)> { match expr.kind { ExprKind::Call(path, args) => { if let ExprKind::Path(ref qpath) = path.kind { @@ -99,12 +99,12 @@ fn min_max<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(MinMax, Cons } } -fn fetch_const<'a>( - cx: &LateContext<'_>, +fn fetch_const<'a, 'tcx>( + cx: &LateContext<'tcx>, receiver: Option<&'a Expr<'a>>, args: &'a [Expr<'a>], m: MinMax, -) -> Option<(MinMax, Constant, &'a Expr<'a>)> { +) -> Option<(MinMax, Constant<'tcx>, &'a Expr<'a>)> { let mut args = receiver.into_iter().chain(args); let first_arg = args.next()?; let second_arg = args.next()?; diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 3752b9a946f8..303f01256908 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -16,9 +16,12 @@ use rustc_span::source_map::{ExpnKind, Span}; use clippy_utils::sugg::Sugg; use clippy_utils::{ - get_parent_expr, in_constant, is_integer_literal, is_no_std_crate, iter_input_pats, last_path_segment, SpanlessEq, + get_parent_expr, in_constant, is_integer_literal, is_lint_allowed, is_no_std_crate, iter_input_pats, + last_path_segment, SpanlessEq, }; +use crate::ref_patterns::REF_PATTERNS; + declare_clippy_lint! { /// ### What it does /// Checks for function arguments and let bindings denoted as @@ -162,6 +165,10 @@ impl<'tcx> LateLintPass<'tcx> for LintPass { return; } for arg in iter_input_pats(decl, body) { + // Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue. + if !is_lint_allowed(cx, REF_PATTERNS, arg.pat.hir_id) { + return; + } if let PatKind::Binding(BindingAnnotation(ByRef::Yes, _), ..) = arg.pat.kind { span_lint( cx, @@ -180,6 +187,8 @@ impl<'tcx> LateLintPass<'tcx> for LintPass { if let StmtKind::Local(local) = stmt.kind; if let PatKind::Binding(BindingAnnotation(ByRef::Yes, mutabl), .., name, None) = local.pat.kind; if let Some(init) = local.init; + // Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue. + if is_lint_allowed(cx, REF_PATTERNS, local.pat.hir_id); then { let ctxt = local.span.ctxt(); let mut app = Applicability::MachineApplicable; diff --git a/clippy_lints/src/misc_early/mixed_case_hex_literals.rs b/clippy_lints/src/misc_early/mixed_case_hex_literals.rs index ddb8b9173a53..9151cc633200 100644 --- a/clippy_lints/src/misc_early/mixed_case_hex_literals.rs +++ b/clippy_lints/src/misc_early/mixed_case_hex_literals.rs @@ -13,7 +13,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, suffix: &str, lit_sni return; } let mut seen = (false, false); - for ch in lit_snip.as_bytes()[2..=maybe_last_sep_idx].iter() { + for ch in &lit_snip.as_bytes()[2..=maybe_last_sep_idx] { match ch { b'a'..=b'f' => seen.0 = true, b'A'..=b'F' => seen.1 = true, diff --git a/clippy_lints/src/misc_early/mod.rs b/clippy_lints/src/misc_early/mod.rs index 78be6b9e23fa..8fe5584b19c6 100644 --- a/clippy_lints/src/misc_early/mod.rs +++ b/clippy_lints/src/misc_early/mod.rs @@ -2,6 +2,7 @@ mod builtin_type_shadow; mod double_neg; mod literal_suffix; mod mixed_case_hex_literals; +mod redundant_at_rest_pattern; mod redundant_pattern; mod unneeded_field_pattern; mod unneeded_wildcard_pattern; @@ -318,6 +319,49 @@ declare_clippy_lint! { "tuple patterns with a wildcard pattern (`_`) is next to a rest pattern (`..`)" } +declare_clippy_lint! { + /// ### What it does + /// Checks for `[all @ ..]` patterns. + /// + /// ### Why is this bad? + /// In all cases, `all` works fine and can often make code simpler, as you possibly won't need + /// to convert from say a `Vec` to a slice by dereferencing. + /// + /// ### Example + /// ```rust,ignore + /// if let [all @ ..] = &*v { + /// // NOTE: Type is a slice here + /// println!("all elements: {all:#?}"); + /// } + /// ``` + /// Use instead: + /// ```rust,ignore + /// if let all = v { + /// // NOTE: Type is a `Vec` here + /// println!("all elements: {all:#?}"); + /// } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 3376c714e (Add note to remove `if` statement altogether) + /// // or + /// println!("all elements: {v:#?}"); + /// ``` + #[clippy::version = "1.72.0"] + pub REDUNDANT_AT_REST_PATTERN, +======= + /// ``` + #[clippy::version = "1.72.0"] +<<<<<<< HEAD + pub REDUNDANT_REST_PATTERN, +>>>>>>> 9a8347ded (New lint [`redundant_rest_pattern`]) +======= + pub REDUNDANT_AT_REST_PATTERN, +>>>>>>> e9ced1251 (Rename the lint) + complexity, + "checks for `[all @ ..]` where `all` would suffice" +} + declare_lint_pass!(MiscEarlyLints => [ UNNEEDED_FIELD_PATTERN, DUPLICATE_UNDERSCORE_ARGUMENT, @@ -329,6 +373,15 @@ declare_lint_pass!(MiscEarlyLints => [ BUILTIN_TYPE_SHADOW, REDUNDANT_PATTERN, UNNEEDED_WILDCARD_PATTERN, +<<<<<<< HEAD +<<<<<<< HEAD + REDUNDANT_AT_REST_PATTERN, +======= + REDUNDANT_REST_PATTERN, +>>>>>>> 9a8347ded (New lint [`redundant_rest_pattern`]) +======= + REDUNDANT_AT_REST_PATTERN, +>>>>>>> e9ced1251 (Rename the lint) ]); impl EarlyLintPass for MiscEarlyLints { @@ -339,8 +392,21 @@ impl EarlyLintPass for MiscEarlyLints { } fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) { + if in_external_macro(cx.sess(), pat.span) { + return; + } + unneeded_field_pattern::check(cx, pat); redundant_pattern::check(cx, pat); +<<<<<<< HEAD +<<<<<<< HEAD + redundant_at_rest_pattern::check(cx, pat); +======= + redundant_rest_pattern::check(cx, pat); +>>>>>>> 9a8347ded (New lint [`redundant_rest_pattern`]) +======= + redundant_at_rest_pattern::check(cx, pat); +>>>>>>> e9ced1251 (Rename the lint) unneeded_wildcard_pattern::check(cx, pat); } diff --git a/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs b/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs new file mode 100644 index 000000000000..0c81ee5eced8 --- /dev/null +++ b/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs @@ -0,0 +1,26 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use rustc_ast::{Pat, PatKind}; +use rustc_errors::Applicability; +use rustc_lint::{EarlyContext, LintContext}; +use rustc_middle::lint::in_external_macro; + +use super::REDUNDANT_AT_REST_PATTERN; + +pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) { + if !in_external_macro(cx.sess(), pat.span) + && let PatKind::Slice(slice) = &pat.kind + && let [one] = &**slice + && let PatKind::Ident(annotation, ident, Some(rest)) = &one.kind + && let PatKind::Rest = rest.kind + { + span_lint_and_sugg( + cx, + REDUNDANT_AT_REST_PATTERN, + pat.span, + "using a rest pattern to bind an entire slice to a local", + "this is better represented with just the binding", + format!("{}{ident}", annotation.prefix_str()), + Applicability::MachineApplicable, + ); + } +} diff --git a/clippy_lints/src/mismatching_type_param_order.rs b/clippy_lints/src/mismatching_type_param_order.rs index 9de4b56b77b5..28e041dee0db 100644 --- a/clippy_lints/src/mismatching_type_param_order.rs +++ b/clippy_lints/src/mismatching_type_param_order.rs @@ -59,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeParamMismatch { then { // get the name and span of the generic parameters in the Impl let mut impl_params = Vec::new(); - for p in generic_args.args.iter() { + for p in generic_args.args { match p { GenericArg::Type(Ty {kind: TyKind::Path(QPath::Resolved(_, path)), ..}) => impl_params.push((path.segments[0].ident.to_string(), path.span)), diff --git a/clippy_lints/src/missing_assert_message.rs b/clippy_lints/src/missing_assert_message.rs index 2214a568d9c6..4dbb79334caf 100644 --- a/clippy_lints/src/missing_assert_message.rs +++ b/clippy_lints/src/missing_assert_message.rs @@ -36,7 +36,7 @@ declare_clippy_lint! { /// assert!(service.ready, "`service.poll_ready()` must be called first to ensure that service is ready to receive requests"); /// } /// ``` - #[clippy::version = "1.69.0"] + #[clippy::version = "1.70.0"] pub MISSING_ASSERT_MESSAGE, restriction, "checks assertions without a custom panic message" diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index f1831a30461a..3b7eccad79df 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -154,7 +154,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, &self.msrv) { if cx.tcx.is_const_fn_raw(def_id.to_def_id()) { - cx.tcx.sess.span_err(span, err.as_ref()); + cx.tcx.sess.span_err(span, err); } } else { span_lint(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`"); diff --git a/clippy_lints/src/missing_enforced_import_rename.rs b/clippy_lints/src/missing_enforced_import_rename.rs index 773174679dbd..96d83e114a41 100644 --- a/clippy_lints/src/missing_enforced_import_rename.rs +++ b/clippy_lints/src/missing_enforced_import_rename.rs @@ -1,8 +1,11 @@ -use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet_opt}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_opt; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; -use rustc_hir::{def::Res, def_id::DefId, Item, ItemKind, UseKind}; +use rustc_hir::def::Res; +use rustc_hir::def_id::DefId; +use rustc_hir::{Item, ItemKind, UseKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Symbol; diff --git a/clippy_lints/src/missing_fields_in_debug.rs b/clippy_lints/src/missing_fields_in_debug.rs new file mode 100644 index 000000000000..65f030b1297b --- /dev/null +++ b/clippy_lints/src/missing_fields_in_debug.rs @@ -0,0 +1,423 @@ +use std::ops::ControlFlow; + +<<<<<<< HEAD +use clippy_utils::{ + diagnostics::span_lint_and_then, +<<<<<<< HEAD +<<<<<<< HEAD + is_path_lang_item, paths, +======= + paths, +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= + is_path_lang_item, paths, +>>>>>>> a859b0e6d (don't lint enums, update note in lint description) + ty::match_type, + visitors::{for_each_expr, Visitable}, +}; +use rustc_ast::LitKind; +use rustc_data_structures::fx::FxHashSet; +<<<<<<< HEAD +<<<<<<< HEAD +use rustc_hir::Block; +======= +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::ty::match_type; +use clippy_utils::visitors::{for_each_expr, Visitable}; +use clippy_utils::{is_path_lang_item, paths}; +use rustc_ast::LitKind; +use rustc_data_structures::fx::FxHashSet; +use rustc_hir::def::{DefKind, Res}; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_hir::{ + Block, Expr, ExprKind, Impl, ImplItem, ImplItemKind, Item, ItemKind, LangItem, Node, QPath, TyKind, VariantData, +}; +use rustc_lint::{LateContext, LateLintPass}; +<<<<<<< HEAD +use rustc_middle::ty::Ty; +use rustc_middle::ty::TypeckResults; +======= +======= +use rustc_hir::Block; +>>>>>>> a859b0e6d (don't lint enums, update note in lint description) +use rustc_hir::{ + def::{DefKind, Res}, + Expr, ImplItemKind, LangItem, Node, +}; +use rustc_hir::{ExprKind, Impl, ItemKind, QPath, TyKind}; +use rustc_hir::{ImplItem, Item, VariantData}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::Ty; +use rustc_middle::ty::TypeckResults; +<<<<<<< HEAD +use rustc_middle::ty::{EarlyBinder, Ty}; +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= +>>>>>>> a859b0e6d (don't lint enums, update note in lint description) +======= +use rustc_middle::ty::{Ty, TypeckResults}; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::{sym, Span, Symbol}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for manual [`core::fmt::Debug`](https://doc.rust-lang.org/core/fmt/trait.Debug.html) implementations that do not use all fields. + /// + /// ### Why is this bad? + /// A common mistake is to forget to update manual `Debug` implementations when adding a new field + /// to a struct or a new variant to an enum. + /// + /// At the same time, it also acts as a style lint to suggest using [`core::fmt::DebugStruct::finish_non_exhaustive`](https://doc.rust-lang.org/core/fmt/struct.DebugStruct.html#method.finish_non_exhaustive) + /// for the times when the user intentionally wants to leave out certain fields (e.g. to hide implementation details). + /// + /// ### Known problems + /// This lint works based on the `DebugStruct` helper types provided by the `Formatter`, + /// so this won't detect `Debug` impls that use the `write!` macro. + /// Oftentimes there is more logic to a `Debug` impl if it uses `write!` macro, so it tries + /// to be on the conservative side and not lint in those cases in an attempt to prevent false positives. + /// +<<<<<<< HEAD +<<<<<<< HEAD + /// This lint also does not look through function calls, so calling a function does not consider fields + /// used inside of that function as used by the `Debug` impl. + /// + /// Lastly, it also ignores tuple structs as their `DebugTuple` formatter does not have a `finish_non_exhaustive` + /// method, as well as enums because their exhaustiveness is already checked by the compiler when matching on the enum, + /// making it much less likely to accidentally forget to update the `Debug` impl when adding a new variant. +======= + /// This lint also does not look through function calls, so calling `.field(self.as_slice())` for example + /// does not consider fields used inside of `as_slice()` as used by the `Debug` impl. + /// + /// Lastly, it also ignores tuple structs as their `DebugTuple` formatter does not have a `finish_non_exhaustive` + /// method. +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= + /// This lint also does not look through function calls, so calling a function does not consider fields + /// used inside of that function as used by the `Debug` impl. + /// + /// Lastly, it also ignores tuple structs as their `DebugTuple` formatter does not have a `finish_non_exhaustive` + /// method, as well as enums because their exhaustiveness is already checked by the compiler when matching on the enum, + /// making it much less likely to accidentally forget to update the `Debug` impl when adding a new variant. +>>>>>>> a859b0e6d (don't lint enums, update note in lint description) + /// + /// ### Example + /// ```rust + /// use std::fmt; + /// struct Foo { + /// data: String, + /// // implementation detail + /// hidden_data: i32 + /// } + /// impl fmt::Debug for Foo { + /// fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + /// formatter + /// .debug_struct("Foo") + /// .field("data", &self.data) + /// .finish() + /// } + /// } + /// ``` + /// Use instead: + /// ```rust + /// use std::fmt; + /// struct Foo { + /// data: String, + /// // implementation detail + /// hidden_data: i32 + /// } + /// impl fmt::Debug for Foo { + /// fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + /// formatter + /// .debug_struct("Foo") + /// .field("data", &self.data) + /// .finish_non_exhaustive() + /// } + /// } + /// ``` + #[clippy::version = "1.70.0"] + pub MISSING_FIELDS_IN_DEBUG, + pedantic, + "missing fields in manual `Debug` implementation" +} +declare_lint_pass!(MissingFieldsInDebug => [MISSING_FIELDS_IN_DEBUG]); + +fn report_lints(cx: &LateContext<'_>, span: Span, span_notes: Vec<(Span, &'static str)>) { + span_lint_and_then( + cx, + MISSING_FIELDS_IN_DEBUG, + span, + "manual `Debug` impl does not include all fields", + |diag| { + for (span, note) in span_notes { + diag.span_note(span, note); + } + diag.help("consider including all fields in this `Debug` impl") + .help("consider calling `.finish_non_exhaustive()` if you intend to ignore fields"); + }, + ); +} + +/// Checks if we should lint in a block of code +/// +/// The way we check for this condition is by checking if there is +/// a call to `Formatter::debug_struct` but no call to `.finish_non_exhaustive()`. +fn should_lint<'tcx>( + cx: &LateContext<'tcx>, + typeck_results: &TypeckResults<'tcx>, + block: impl Visitable<'tcx>, +) -> bool { + // Is there a call to `DebugStruct::finish_non_exhaustive`? Don't lint if there is. + let mut has_finish_non_exhaustive = false; + // Is there a call to `DebugStruct::debug_struct`? Do lint if there is. + let mut has_debug_struct = false; + + for_each_expr(block, |expr| { + if let ExprKind::MethodCall(path, recv, ..) = &expr.kind { + let recv_ty = typeck_results.expr_ty(recv).peel_refs(); + + if path.ident.name == sym::debug_struct && match_type(cx, recv_ty, &paths::FORMATTER) { + has_debug_struct = true; + } else if path.ident.name == sym!(finish_non_exhaustive) && match_type(cx, recv_ty, &paths::DEBUG_STRUCT) { + has_finish_non_exhaustive = true; + } + } + ControlFlow::::Continue(()) + }); + + !has_finish_non_exhaustive && has_debug_struct +} + +/// Checks if the given expression is a call to `DebugStruct::field` +/// and the first argument to it is a string literal and if so, returns it +/// +/// Example: `.field("foo", ....)` returns `Some("foo")` +fn as_field_call<'tcx>( + cx: &LateContext<'tcx>, + typeck_results: &TypeckResults<'tcx>, + expr: &Expr<'_>, +) -> Option { + if let ExprKind::MethodCall(path, recv, [debug_field, _], _) = &expr.kind + && let recv_ty = typeck_results.expr_ty(recv).peel_refs() + && match_type(cx, recv_ty, &paths::DEBUG_STRUCT) + && path.ident.name == sym::field + && let ExprKind::Lit(lit) = &debug_field.kind + && let LitKind::Str(sym, ..) = lit.node + { + Some(sym) + } else { + None + } +} + +/// Attempts to find unused fields assuming that the item is a struct +fn check_struct<'tcx>( + cx: &LateContext<'tcx>, + typeck_results: &TypeckResults<'tcx>, + block: &'tcx Block<'tcx>, + self_ty: Ty<'tcx>, + item: &'tcx Item<'tcx>, + data: &VariantData<'_>, +) { + // Is there a "direct" field access anywhere (i.e. self.foo)? + // We don't want to lint if there is not, because the user might have + // a newtype struct and use fields from the wrapped type only. + let mut has_direct_field_access = false; + let mut field_accesses = FxHashSet::default(); + + for_each_expr(block, |expr| { + if let ExprKind::Field(target, ident) = expr.kind + && let target_ty = typeck_results.expr_ty_adjusted(target).peel_refs() + && target_ty == self_ty + { + field_accesses.insert(ident.name); + has_direct_field_access = true; + } else if let Some(sym) = as_field_call(cx, typeck_results, expr) { + field_accesses.insert(sym); + } + ControlFlow::::Continue(()) + }); + + let span_notes = data + .fields() + .iter() + .filter_map(|field| { +<<<<<<< HEAD +<<<<<<< HEAD + if field_accesses.contains(&field.ident.name) || is_path_lang_item(cx, field.ty, LangItem::PhantomData) { +======= + let EarlyBinder(field_ty) = cx.tcx.type_of(field.def_id); + if field_accesses.contains(&field.ident.name) || field_ty.is_phantom_data() { +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= + if field_accesses.contains(&field.ident.name) || is_path_lang_item(cx, field.ty, LangItem::PhantomData) { +>>>>>>> a859b0e6d (don't lint enums, update note in lint description) + None + } else { + Some((field.span, "this field is unused")) + } + }) + .collect::>(); + + // only lint if there's also at least one direct field access to allow patterns + // where one might have a newtype struct and uses fields from the wrapped type + if !span_notes.is_empty() && has_direct_field_access { + report_lints(cx, item.span, span_notes); + } +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +/// Attempts to find unused fields in variants assuming that +/// the item is an enum. +/// +/// Currently, only simple cases are detected where the user +/// matches on `self` and calls `debug_struct` inside of the arms +fn check_enum<'tcx>( + cx: &LateContext<'tcx>, + typeck_results: &TypeckResults<'tcx>, + block: &'tcx Block<'tcx>, + self_ty: Ty<'tcx>, + item: &'tcx Item<'tcx>, +) { + let Some(arms) = for_each_expr(block, |expr| { + if let ExprKind::Match(val, arms, MatchSource::Normal) = expr.kind + && let match_ty = typeck_results.expr_ty_adjusted(val).peel_refs() + && match_ty == self_ty + { + ControlFlow::Break(arms) + } else { + ControlFlow::Continue(()) + } + }) else { + return; + }; + + let mut span_notes = Vec::new(); + + for arm in arms { + if !should_lint(cx, typeck_results, arm.body) { + continue; + } + + arm.pat.walk_always(|pat| match pat.kind { + PatKind::Wild => span_notes.push((pat.span, "unused field here due to wildcard `_`")), + PatKind::Tuple(_, rest) | PatKind::TupleStruct(.., rest) if rest.as_opt_usize().is_some() => { + span_notes.push((pat.span, "more unused fields here due to rest pattern `..`")); + }, + PatKind::Struct(.., true) => { + span_notes.push((pat.span, "more unused fields here due to rest pattern `..`")); + }, + _ => {}, + }); + + let mut field_accesses = FxHashSet::default(); + let mut check_field_access = |sym, expr| { + if !typeck_results.expr_ty(expr).is_phantom_data() { + arm.pat.each_binding(|_, _, _, pat_ident| { + if sym == pat_ident.name { + field_accesses.insert(pat_ident); + } + }); + } + }; + + for_each_expr(arm.body, |expr| { + if let ExprKind::Path(QPath::Resolved(_, path)) = expr.kind && let Some(segment) = path.segments.first() + { + check_field_access(segment.ident.name, expr); + } else if let Some(sym) = as_field_call(cx, typeck_results, expr) { + check_field_access(sym, expr); + } + ControlFlow::::Continue(()) + }); + + arm.pat.each_binding(|_, _, span, pat_ident| { + if !field_accesses.contains(&pat_ident) { + span_notes.push((span, "the field referenced by this binding is unused")); + } + }); + } + + if !span_notes.is_empty() { + report_lints(cx, item.span, span_notes); + } +} + +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= +>>>>>>> a859b0e6d (don't lint enums, update note in lint description) +impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx rustc_hir::Item<'tcx>) { + // is this an `impl Debug for X` block? + if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, items, .. }) = item.kind + && let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res + && let TyKind::Path(QPath::Resolved(_, self_path)) = &self_ty.kind +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 1cf95a9d5 (don't call `type_of` on generic params) + // don't trigger if self is a generic parameter, e.g. `impl Debug for T` + // this can only happen in core itself, where the trait is defined, + // but it caused ICEs in the past: + // https://github.com/rust-lang/rust-clippy/issues/10887 + && !matches!(self_path.res, Res::Def(DefKind::TyParam, _)) +<<<<<<< HEAD +======= +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= +>>>>>>> 1cf95a9d5 (don't call `type_of` on generic params) +======= + // make sure that the self type is either a struct, an enum or a union + // this prevents ICEs such as when self is a type parameter or a primitive type + // (see #10887, #11063) + && let Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, self_path_did) = self_path.res +>>>>>>> 555ceb83f ([`missing_fields_in_debug`]: make sure `self` is an adt) + && cx.match_def_path(trait_def_id, &[sym::core, sym::fmt, sym::Debug]) + // don't trigger if this impl was derived + && !cx.tcx.has_attr(item.owner_id, sym::automatically_derived) + && !item.span.from_expansion() + // find `Debug::fmt` function + && let Some(fmt_item) = items.iter().find(|i| i.ident.name == sym::fmt) + && let ImplItem { kind: ImplItemKind::Fn(_, body_id), .. } = cx.tcx.hir().impl_item(fmt_item.id) + && let body = cx.tcx.hir().body(*body_id) + && let ExprKind::Block(block, _) = body.value.kind + // inspect `self` +<<<<<<< HEAD +<<<<<<< HEAD + && let self_ty = cx.tcx.type_of(self_path.res.def_id()).skip_binder().peel_refs() +======= + && let self_ty = cx.tcx.type_of(self_path.res.def_id()).0.peel_refs() +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= + && let self_ty = cx.tcx.type_of(self_path_did).skip_binder().peel_refs() +>>>>>>> 555ceb83f ([`missing_fields_in_debug`]: make sure `self` is an adt) + && let Some(self_adt) = self_ty.ty_adt_def() + && let Some(self_def_id) = self_adt.did().as_local() + && let Some(Node::Item(self_item)) = cx.tcx.hir().find_by_def_id(self_def_id) + // NB: can't call cx.typeck_results() as we are not in a body + && let typeck_results = cx.tcx.typeck_body(*body_id) + && should_lint(cx, typeck_results, block) + { +<<<<<<< HEAD +<<<<<<< HEAD + // we intentionally only lint structs, see lint description + if let ItemKind::Struct(data, _) = &self_item.kind { + check_struct(cx, typeck_results, block, self_ty, item, data); +======= + match &self_item.kind { + ItemKind::Struct(data, _) => check_struct(cx, typeck_results, block, self_ty, item, data), + ItemKind::Enum(..) => check_enum(cx, typeck_results, block, self_ty, item), + _ => {} +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= + // we intentionally only lint structs, see lint description + if let ItemKind::Struct(data, _) = &self_item.kind { + check_struct(cx, typeck_results, block, self_ty, item, data); +>>>>>>> a859b0e6d (don't lint enums, update note in lint description) + } + } + } +} diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index 5a459548153a..a41d5a9ce8d2 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { match tit_.kind { hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {}, hir::TraitItemKind::Fn(..) => { - if cx.tcx.impl_defaultness(tit.id.owner_id).has_value() { + if cx.tcx.defaultness(tit.id.owner_id).has_value() { // trait method with default body needs inline in case // an impl is not provided let desc = "a default trait method"; diff --git a/clippy_lints/src/missing_trait_methods.rs b/clippy_lints/src/missing_trait_methods.rs index e99081ad0620..1adecd2caaca 100644 --- a/clippy_lints/src/missing_trait_methods.rs +++ b/clippy_lints/src/missing_trait_methods.rs @@ -12,7 +12,7 @@ declare_clippy_lint! { /// Checks if a provided method is used implicitly by a trait /// implementation. A usage example would be a wrapper where every method /// should perform some operation before delegating to the inner type's - /// implemenation. + /// implementation. /// /// This lint should typically be enabled on a specific trait `impl` item /// rather than globally. diff --git a/clippy_lints/src/mixed_read_write_in_expression.rs b/clippy_lints/src/mixed_read_write_in_expression.rs index f0be7771bb1a..a59a8f303011 100644 --- a/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/clippy_lints/src/mixed_read_write_in_expression.rs @@ -114,7 +114,7 @@ struct DivergenceVisitor<'a, 'tcx> { impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> { fn maybe_walk_expr(&mut self, e: &'tcx Expr<'_>) { match e.kind { - ExprKind::Closure { .. } => {}, + ExprKind::Closure(..) | ExprKind::If(..) | ExprKind::Loop(..) => {}, ExprKind::Match(e, arms, _) => { self.visit_expr(e); for arm in arms { @@ -128,6 +128,7 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> { _ => walk_expr(self, e), } } + fn report_diverging_sub_expr(&mut self, e: &Expr<'_>) { span_lint(self.cx, DIVERGING_SUB_EXPRESSION, e.span, "sub-expression diverges"); } @@ -136,6 +137,37 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> { fn visit_expr(&mut self, e: &'tcx Expr<'_>) { match e.kind { + // fix #10776 +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 35aff1ae8 (refactor) + ExprKind::Block(block, ..) => match (block.stmts, block.expr) { + ([], Some(e)) => self.visit_expr(e), + ([stmt], None) => match stmt.kind { + StmtKind::Expr(e) | StmtKind::Semi(e) => self.visit_expr(e), + _ => {}, + }, + _ => {}, +<<<<<<< HEAD +======= + ExprKind::Block(block, ..) => { + if let Some(e) = block.expr && block.stmts.is_empty() { + self.visit_expr(e); + + return; + } + + if let [stmt, rest @ ..] = block.stmts && rest.is_empty() { + match stmt.kind { + StmtKind::Expr(e) | StmtKind::Semi(e) => self.visit_expr(e), + _ => {}, + } + } +>>>>>>> 5825b9e3e (actually fix it) +======= +>>>>>>> 35aff1ae8 (refactor) + }, ExprKind::Continue(_) | ExprKind::Break(_, _) | ExprKind::Ret(_) => self.report_diverging_sub_expr(e), ExprKind::Call(func, _) => { let typ = self.cx.typeck_results().expr_ty(func); diff --git a/clippy_lints/src/module_style.rs b/clippy_lints/src/module_style.rs index 349fcd2274d3..fbb5fbe6fb81 100644 --- a/clippy_lints/src/module_style.rs +++ b/clippy_lints/src/module_style.rs @@ -2,6 +2,7 @@ use rustc_ast::ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext}; use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::def_id::LOCAL_CRATE; use rustc_span::{FileName, SourceFile, Span, SyntaxContext}; use std::ffi::OsStr; use std::path::{Component, Path}; @@ -90,7 +91,31 @@ impl EarlyLintPass for ModStyle { // `{ foo => path/to/foo.rs, .. } let mut file_map = FxHashMap::default(); for file in files.iter() { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> e11ebbd5e (Move continue into if statement) + if let FileName::Real(name) = &file.name + && let Some(lp) = name.local_path() + && file.cnum == LOCAL_CRATE + { + // [#8887](https://github.com/rust-lang/rust-clippy/issues/8887) + // Only check files in the current crate. + // Fix false positive that crate dependency in workspace sub directory + // is checked unintentionally. +<<<<<<< HEAD +======= if let FileName::Real(name) = &file.name && let Some(lp) = name.local_path() { + if file.cnum != LOCAL_CRATE { + // [#8887](https://github.com/rust-lang/rust-clippy/issues/8887) + // Only check files in the current crate. + // Fix false positive that crate dependency in workspace sub directory + // is checked unintentionally. + continue; + } +>>>>>>> 65b93a5b4 (Fix false positive of [self_named_module_files] and [mod_module_files]) +======= +>>>>>>> e11ebbd5e (Move continue into if statement) let path = if lp.is_relative() { lp } else if let Ok(relative) = lp.strip_prefix(trim_to_src) { diff --git a/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 5418616ded01..fe35126aab21 100644 --- a/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -1,12 +1,8 @@ -use clippy_utils::{ - diagnostics::span_lint_and_then, - visitors::{for_each_expr_with_closures, Descend, Visitable}, -}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::visitors::{for_each_expr_with_closures, Descend, Visitable}; use core::ops::ControlFlow::Continue; -use hir::{ - def::{DefKind, Res}, - BlockCheckMode, ExprKind, QPath, UnOp, Unsafety, -}; +use hir::def::{DefKind, Res}; +use hir::{BlockCheckMode, ExprKind, QPath, UnOp, Unsafety}; use rustc_ast::Mutability; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; @@ -59,7 +55,7 @@ declare_clippy_lint! { /// unsafe { char::from_u32_unchecked(int_value) } /// } /// ``` - #[clippy::version = "1.68.0"] + #[clippy::version = "1.69.0"] pub MULTIPLE_UNSAFE_OPS_PER_BLOCK, restriction, "more than one unsafe operation per `unsafe` block" @@ -138,7 +134,7 @@ fn collect_unsafe_exprs<'tcx>( .type_dependent_def_id(expr.hir_id) .map(|def_id| cx.tcx.fn_sig(def_id)) { - if sig.0.unsafety() == Unsafety::Unsafe { + if sig.skip_binder().unsafety() == Unsafety::Unsafe { unsafe_ops.push(("unsafe method call occurs here", expr.span)); } } diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index c87059bf61de..4727a8fd5cf1 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -3,10 +3,18 @@ //! This lint is **warn** by default use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; -use clippy_utils::higher; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; -use clippy_utils::{get_parent_node, is_else_clause, is_expn_of, peel_blocks, peel_blocks_with_stmt}; +use clippy_utils::{ +<<<<<<< HEAD + get_parent_node, higher, is_else_clause, is_expn_of, peel_blocks, peel_blocks_with_stmt, span_extract_comment, + SpanlessEq, +}; +======= + get_parent_node, is_else_clause, is_expn_of, peel_blocks, peel_blocks_with_stmt, span_extract_comment, +}; +use clippy_utils::{higher, SpanlessEq}; +>>>>>>> e4f5d83fa (Fixed formatting.) use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, Node, UnOp}; @@ -77,7 +85,43 @@ declare_clippy_lint! { "comparing a variable to a boolean, e.g., `if x == true` or `if x != true`" } -declare_lint_pass!(NeedlessBool => [NEEDLESS_BOOL]); +declare_clippy_lint! { + /// ### What it does + /// Checks for expressions of the form `if c { x = true } else { x = false }` + /// (or vice versa) and suggest assigning the variable directly from the + /// condition. + /// + /// ### Why is this bad? + /// Redundant code. + /// + /// ### Example + /// ```rust,ignore + /// # fn must_keep(x: i32, y: i32) -> bool { x == y } + /// # let x = 32; let y = 10; + /// # let mut skip: bool; + /// if must_keep(x, y) { + /// skip = false; + /// } else { + /// skip = true; + /// } + /// ``` + /// Use instead: + /// ```rust,ignore + /// # fn must_keep(x: i32, y: i32) -> bool { x == y } + /// # let x = 32; let y = 10; + /// # let mut skip: bool; + /// skip = !must_keep(x, y); + /// ``` +<<<<<<< HEAD + #[clippy::version = "1.71.0"] +======= + #[clippy::version = "1.69.0"] +>>>>>>> e4f5d83fa (Fixed formatting.) + pub NEEDLESS_BOOL_ASSIGN, + complexity, + "setting the same boolean variable in both branches of an if-statement" +} +declare_lint_pass!(NeedlessBool => [NEEDLESS_BOOL, NEEDLESS_BOOL_ASSIGN]); fn condition_needs_parentheses(e: &Expr<'_>) -> bool { let mut inner = e; @@ -112,7 +156,7 @@ fn is_parent_stmt(cx: &LateContext<'_>, id: HirId) -> bool { impl<'tcx> LateLintPass<'tcx> for NeedlessBool { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { use self::Expression::{Bool, RetBool}; - if e.span.from_expansion() { + if e.span.from_expansion() || !span_extract_comment(cx.tcx.sess.source_map(), e.span).is_empty() { return; } if let Some(higher::If { @@ -173,6 +217,51 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool { _ => (), } } + if let Some((lhs_a, a)) = fetch_assign(then) && + let Some((lhs_b, b)) = fetch_assign(r#else) && +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b) +======= + SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b) && + span_extract_comment(cx.tcx.sess.source_map(), e.span).is_empty() +<<<<<<< HEAD +>>>>>>> 69da902f4 (Detect if expressions with boolean assignments to the same target) +======= + SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b) +>>>>>>> c5d4b04dd (needless_bool: do not simplify code if it loses comments) +======= +>>>>>>> 7e9abb311 (Merge commit '371120bdbf58a331db5dcfb2d9cddc040f486de8' into clippyup) +======= + SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b) +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= + SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + { + let mut applicability = Applicability::MachineApplicable; + let cond = Sugg::hir_with_applicability(cx, cond, "..", &mut applicability); + let lhs = snippet_with_applicability(cx, lhs_a.span, "..", &mut applicability); + let sugg = if a == b { + format!("{cond}; {lhs} = {a:?};") + } else { + format!("{lhs} = {};", if a { cond } else { !cond }) + }; + span_lint_and_sugg( + cx, + NEEDLESS_BOOL_ASSIGN, + e.span, + "this if-then-else expression assigns a bool literal", + "you can reduce it to", + sugg, + applicability + ); + } } } } @@ -376,3 +465,11 @@ fn fetch_bool_expr(expr: &Expr<'_>) -> Option { } None } + +fn fetch_assign<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(&'tcx Expr<'tcx>, bool)> { + if let ExprKind::Assign(lhs, rhs, _) = peel_blocks_with_stmt(expr).kind { + fetch_bool_expr(rhs).map(|b| (lhs, b)) + } else { + None + } +} diff --git a/clippy_lints/src/needless_else.rs b/clippy_lints/src/needless_else.rs new file mode 100644 index 000000000000..3373e5011a02 --- /dev/null +++ b/clippy_lints/src/needless_else.rs @@ -0,0 +1,102 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::source::snippet_opt; +use clippy_utils::{diagnostics::span_lint_and_sugg, source::trim_span}; +======= +use clippy_utils::{diagnostics::span_lint_and_sugg, source::trim_span, span_extract_comment}; +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= +use clippy_utils::source::snippet_opt; +use clippy_utils::{diagnostics::span_lint_and_sugg, source::trim_span}; +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) +======= +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::{snippet_opt, trim_span}; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_ast::ast::{Expr, ExprKind}; +use rustc_errors::Applicability; +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for empty `else` branches. + /// + /// ### Why is this bad? + /// An empty else branch does nothing and can be removed. + /// + /// ### Example + /// ```rust + ///# fn check() -> bool { true } + /// if check() { + /// println!("Check successful!"); + /// } else { + /// } + /// ``` + /// Use instead: + /// ```rust + ///# fn check() -> bool { true } + /// if check() { + /// println!("Check successful!"); + /// } + /// ``` + #[clippy::version = "1.71.0"] + pub NEEDLESS_ELSE, + style, + "empty else branch" +} +declare_lint_pass!(NeedlessElse => [NEEDLESS_ELSE]); + +impl EarlyLintPass for NeedlessElse { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) + if let ExprKind::If(_, then_block, Some(else_clause)) = &expr.kind + && let ExprKind::Block(block, _) = &else_clause.kind + && !expr.span.from_expansion() + && !else_clause.span.from_expansion() + && block.stmts.is_empty() + && let Some(trimmed) = expr.span.trim_start(then_block.span) + && let span = trim_span(cx.sess().source_map(), trimmed) + && let Some(else_snippet) = snippet_opt(cx, span) + // Ignore else blocks that contain comments or #[cfg]s + && !else_snippet.contains(['/', '#']) + { + span_lint_and_sugg( + cx, + NEEDLESS_ELSE, + span, + "this `else` branch is empty", + "you can remove it", + String::new(), + Applicability::MachineApplicable, + ); + } +<<<<<<< HEAD +======= + if let ExprKind::If(_, then_block, Some(else_clause)) = &expr.kind && + let ExprKind::Block(block, _) = &else_clause.kind && + !expr.span.from_expansion() && + !else_clause.span.from_expansion() && + block.stmts.is_empty() { + let span = trim_span(cx.sess().source_map(), expr.span.trim_start(then_block.span).unwrap()); + if span_extract_comment(cx.sess().source_map(), span).is_empty() { + span_lint_and_sugg( + cx, + NEEDLESS_ELSE, + span, + "this else branch is empty", + "you can remove it", + String::new(), + Applicability::MachineApplicable, + ); + } + } +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) + } +} diff --git a/clippy_lints/src/needless_for_each.rs b/clippy_lints/src/needless_for_each.rs index c3b633fd6a03..463e188fc8e0 100644 --- a/clippy_lints/src/needless_for_each.rs +++ b/clippy_lints/src/needless_for_each.rs @@ -1,11 +1,10 @@ use rustc_errors::Applicability; -use rustc_hir::{ - intravisit::{walk_expr, Visitor}, - Closure, Expr, ExprKind, Stmt, StmtKind, -}; +use rustc_hir::intravisit::{walk_expr, Visitor}; +use rustc_hir::{Closure, Expr, ExprKind, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::{source_map::Span, sym, Symbol}; +use rustc_span::source_map::Span; +use rustc_span::{sym, Symbol}; use if_chain::if_chain; diff --git a/clippy_lints/src/needless_if.rs b/clippy_lints/src/needless_if.rs new file mode 100644 index 000000000000..7ed1b5ac3e8c --- /dev/null +++ b/clippy_lints/src/needless_if.rs @@ -0,0 +1,190 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::{diagnostics::span_lint_and_sugg, higher::If, is_from_proc_macro, source::snippet_opt}; +======= +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::higher::If; +use clippy_utils::is_from_proc_macro; +use clippy_utils::source::snippet_opt; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_errors::Applicability; +use rustc_hir::{ExprKind, Stmt, StmtKind}; +======= +use clippy_utils::{diagnostics::span_lint_and_sugg, is_from_proc_macro, source::snippet_with_applicability}; +use rustc_errors::Applicability; +<<<<<<< HEAD +use rustc_hir::{Expr, ExprKind, Node}; +>>>>>>> 26f50395b (Add `needless_if` lint) +======= +use rustc_hir::{ + intravisit::{walk_expr, Visitor}, + Expr, ExprKind, Node, +}; +>>>>>>> 59bca098f (don't lint on `if let`) +======= +use clippy_utils::{diagnostics::span_lint_and_sugg, higher::If, is_from_proc_macro, source::snippet_opt}; +use rustc_errors::Applicability; +use rustc_hir::{ExprKind, Stmt, StmtKind}; +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + /// Checks for empty `if` branches with no else branch. + /// + /// ### Why is this bad? + /// It can be entirely omitted, and often the condition too. + /// + /// ### Known issues + /// This will usually only suggest to remove the `if` statement, not the condition. Other lints + /// such as `no_effect` will take care of removing the condition if it's unnecessary. + /// + /// ### Example + /// ```rust,ignore + /// if really_expensive_condition(&i) {} + /// if really_expensive_condition_with_side_effects(&mut i) {} + /// ``` + /// Use instead: + /// ```rust,ignore + /// // + /// really_expensive_condition_with_side_effects(&mut i); +======= +======= + /// Checks for empty `if` statements with no else branch. +>>>>>>> b2bdc37a5 (add description) +======= + /// Checks for empty `if` branches with no else branch. +>>>>>>> 59bca098f (don't lint on `if let`) + /// + /// ### Why is this bad? + /// It can be entirely omitted, and often the condition too. + /// + /// ### Known issues + /// This will usually only suggest to remove the `if` statement, not the condition. Other lints + /// such as `no_effect` will take care of removing the condition if it's unnecessary. + /// + /// ### Example + /// ```rust,ignore + /// if really_expensive_condition(&i) {} + /// if really_expensive_condition_with_side_effects(&mut i) {} + /// ``` + /// Use instead: +<<<<<<< HEAD + /// ```rust + /// // example code which does not raise clippy warning +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + /// ```rust,ignore + /// // + /// really_expensive_condition_with_side_effects(&mut i); +>>>>>>> b2bdc37a5 (add description) + /// ``` + #[clippy::version = "1.72.0"] + pub NEEDLESS_IF, + complexity, + "checks for empty if branches" +} +declare_lint_pass!(NeedlessIf => [NEEDLESS_IF]); + +impl LateLintPass<'_> for NeedlessIf { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + fn check_stmt<'tcx>(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'tcx>) { + if let StmtKind::Expr(expr) = stmt.kind + && let Some(If {cond, then, r#else: None }) = If::hir(expr) + && let ExprKind::Block(block, ..) = then.kind +<<<<<<< HEAD + && block.stmts.is_empty() + && block.expr.is_none() + && !in_external_macro(cx.sess(), expr.span) + && !is_from_proc_macro(cx, expr) + && let Some(then_snippet) = snippet_opt(cx, then.span) + // Ignore + // - empty macro expansions + // - empty reptitions in macro expansions + // - comments + // - #[cfg]'d out code + && then_snippet.chars().all(|ch| matches!(ch, '{' | '}') || ch.is_ascii_whitespace()) + && let Some(cond_snippet) = snippet_opt(cx, cond.span) + { + span_lint_and_sugg( + cx, + NEEDLESS_IF, + stmt.span, + "this `if` branch is empty", + "you can remove it", + if cond.can_have_side_effects() || !cx.tcx.hir().attrs(stmt.hir_id).is_empty() { + // `{ foo }` or `{ foo } && bar` placed into a statement position would be + // interpreted as a block statement, force it to be an expression + if cond_snippet.starts_with('{') { + format!("({cond_snippet});") + } else { + format!("{cond_snippet};") + } + } else { + String::new() + }, +======= + fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { + if let ExprKind::If(if_expr, block, else_expr) = &expr.kind + && let ExprKind::Block(block, ..) = block.kind +======= +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + && block.stmts.is_empty() + && block.expr.is_none() + && !in_external_macro(cx.sess(), expr.span) + && !is_from_proc_macro(cx, expr) + && let Some(then_snippet) = snippet_opt(cx, then.span) + // Ignore + // - empty macro expansions + // - empty reptitions in macro expansions + // - comments + // - #[cfg]'d out code + && then_snippet.chars().all(|ch| matches!(ch, '{' | '}') || ch.is_ascii_whitespace()) + && let Some(cond_snippet) = snippet_opt(cx, cond.span) + { + span_lint_and_sugg( + cx, + NEEDLESS_IF, + stmt.span, + "this `if` branch is empty", + "you can remove it", +<<<<<<< HEAD +<<<<<<< HEAD + format!("{snippet};"), +>>>>>>> 26f50395b (Add `needless_if` lint) + Applicability::MachineApplicable, +======= + if if_expr.can_have_side_effects() { + format!("{snippet};") + } else { + String::new() + }, + app, +>>>>>>> 59bca098f (don't lint on `if let`) +======= + if cond.can_have_side_effects() || !cx.tcx.hir().attrs(stmt.hir_id).is_empty() { + // `{ foo }` or `{ foo } && bar` placed into a statement position would be + // interpreted as a block statement, force it to be an expression + if cond_snippet.starts_with('{') { + format!("({cond_snippet});") + } else { + format!("{cond_snippet};") + } + } else { + String::new() + }, + Applicability::MachineApplicable, +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + ); + } + } +} diff --git a/clippy_lints/src/needless_parens_on_range_literals.rs b/clippy_lints/src/needless_parens_on_range_literals.rs index 6e54b243c037..7687f598daef 100644 --- a/clippy_lints/src/needless_parens_on_range_literals.rs +++ b/clippy_lints/src/needless_parens_on_range_literals.rs @@ -1,8 +1,6 @@ -use clippy_utils::{ - diagnostics::span_lint_and_then, - higher, - source::{snippet, snippet_with_applicability}, -}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::higher; +use clippy_utils::source::{snippet, snippet_with_applicability}; use rustc_ast::ast; use rustc_errors::Applicability; diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs new file mode 100644 index 000000000000..cdb7ee483054 --- /dev/null +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -0,0 +1,273 @@ +use super::needless_pass_by_value::requires_exact_signature; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::source::snippet; +use clippy_utils::{is_from_proc_macro, is_self}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::intravisit::FnKind; +use rustc_hir::{Body, FnDecl, HirId, HirIdMap, HirIdSet, Impl, ItemKind, Mutability, Node, PatKind}; +use rustc_hir_typeck::expr_use_visitor as euv; +use rustc_infer::infer::TyCtxtInferExt; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::mir::FakeReadCause; +use rustc_middle::ty::{self, Ty}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::def_id::LocalDefId; +use rustc_span::symbol::kw; +use rustc_span::Span; +use rustc_target::spec::abi::Abi; + +declare_clippy_lint! { + /// ### What it does + /// Check if a `&mut` function argument is actually used mutably. + /// + /// Be careful if the function is publicly reexported as it would break compatibility with + /// users of this function. + /// + /// ### Why is this bad? + /// Less `mut` means less fights with the borrow checker. It can also lead to more + /// opportunities for parallelization. + /// + /// ### Example + /// ```rust + /// fn foo(y: &mut i32) -> i32 { + /// 12 + *y + /// } + /// ``` + /// Use instead: + /// ```rust + /// fn foo(y: &i32) -> i32 { + /// 12 + *y + /// } + /// ``` + #[clippy::version = "1.72.0"] + pub NEEDLESS_PASS_BY_REF_MUT, + suspicious, + "using a `&mut` argument when it's not mutated" +} + +#[derive(Copy, Clone)] +pub struct NeedlessPassByRefMut { + avoid_breaking_exported_api: bool, +} + +impl NeedlessPassByRefMut { + pub fn new(avoid_breaking_exported_api: bool) -> Self { + Self { + avoid_breaking_exported_api, + } + } +} + +impl_lint_pass!(NeedlessPassByRefMut => [NEEDLESS_PASS_BY_REF_MUT]); + +fn should_skip<'tcx>( + cx: &LateContext<'tcx>, + input: rustc_hir::Ty<'tcx>, + ty: Ty<'_>, + arg: &rustc_hir::Param<'_>, +) -> bool { + // We check if this a `&mut`. `ref_mutability` returns `None` if it's not a reference. + if !matches!(ty.ref_mutability(), Some(Mutability::Mut)) { + return true; + } + + if is_self(arg) { + return true; + } + + if let PatKind::Binding(.., name, _) = arg.pat.kind { + // If it's a potentially unused variable, we don't check it. + if name.name == kw::Underscore || name.as_str().starts_with('_') { + return true; + } + } + + // All spans generated from a proc-macro invocation are the same... + is_from_proc_macro(cx, &input) +} + +impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut { + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + kind: FnKind<'tcx>, + decl: &'tcx FnDecl<'_>, + body: &'tcx Body<'_>, + span: Span, + fn_def_id: LocalDefId, + ) { + if span.from_expansion() { + return; + } + + let hir_id = cx.tcx.hir().local_def_id_to_hir_id(fn_def_id); + + match kind { + FnKind::ItemFn(.., header) => { + let attrs = cx.tcx.hir().attrs(hir_id); + if header.abi != Abi::Rust || requires_exact_signature(attrs) { + return; + } + }, + FnKind::Method(..) => (), + FnKind::Closure => return, + } + + // Exclude non-inherent impls + if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) { + if matches!( + item.kind, + ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..) + ) { + return; + } + } + + let fn_sig = cx.tcx.fn_sig(fn_def_id).subst_identity(); + let fn_sig = cx.tcx.liberate_late_bound_regions(fn_def_id.to_def_id(), fn_sig); + + // If there are no `&mut` argument, no need to go any further. + if !decl + .inputs + .iter() + .zip(fn_sig.inputs()) + .zip(body.params) + .any(|((&input, &ty), arg)| !should_skip(cx, input, ty, arg)) + { + return; + } + + // Collect variables mutably used and spans which will need dereferencings from the + // function body. + let MutablyUsedVariablesCtxt { mutably_used_vars, .. } = { + let mut ctx = MutablyUsedVariablesCtxt::default(); + let infcx = cx.tcx.infer_ctxt().build(); + euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body); + ctx + }; + + let mut it = decl + .inputs + .iter() + .zip(fn_sig.inputs()) + .zip(body.params) + .filter(|((&input, &ty), arg)| !should_skip(cx, input, ty, arg)) + .peekable(); + if it.peek().is_none() { + return; + } + let show_semver_warning = self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(fn_def_id); + for ((&input, &_), arg) in it { + // Only take `&mut` arguments. + if_chain! { + if let PatKind::Binding(_, canonical_id, ..) = arg.pat.kind; + if !mutably_used_vars.contains(&canonical_id); + if let rustc_hir::TyKind::Ref(_, inner_ty) = input.kind; + then { + // If the argument is never used mutably, we emit the warning. + let sp = input.span; + span_lint_and_then( + cx, + NEEDLESS_PASS_BY_REF_MUT, + sp, + "this argument is a mutable reference, but not used mutably", + |diag| { + diag.span_suggestion( + sp, + "consider changing to".to_string(), + format!( + "&{}", + snippet(cx, cx.tcx.hir().span(inner_ty.ty.hir_id), "_"), + ), + Applicability::Unspecified, + ); + if show_semver_warning { + diag.warn("changing this function will impact semver compatibility"); + } + }, + ); + } + } + } + } +} + +#[derive(Default)] +struct MutablyUsedVariablesCtxt { + mutably_used_vars: HirIdSet, + prev_bind: Option, + aliases: HirIdMap, +} + +impl MutablyUsedVariablesCtxt { + fn add_mutably_used_var(&mut self, mut used_id: HirId) { + while let Some(id) = self.aliases.get(&used_id) { + self.mutably_used_vars.insert(used_id); + used_id = *id; + } + self.mutably_used_vars.insert(used_id); + } +} + +impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt { + fn consume(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, _id: HirId) { + if let euv::Place { + base: euv::PlaceBase::Local(vid), + base_ty, + .. + } = &cmt.place + { + if let Some(bind_id) = self.prev_bind.take() { + self.aliases.insert(bind_id, *vid); + } else if matches!(base_ty.ref_mutability(), Some(Mutability::Mut)) { + self.add_mutably_used_var(*vid); + } + } + } + + fn borrow(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, _id: HirId, borrow: ty::BorrowKind) { + self.prev_bind = None; + if let euv::Place { + base: euv::PlaceBase::Local(vid), + base_ty, + .. + } = &cmt.place + { + // If this is a mutable borrow, it was obviously used mutably so we add it. However + // for `UniqueImmBorrow`, it's interesting because if you do: `array[0] = value` inside + // a closure, it'll return this variant whereas if you have just an index access, it'll + // return `ImmBorrow`. So if there is "Unique" and it's a mutable reference, we add it + // to the mutably used variables set. + if borrow == ty::BorrowKind::MutBorrow + || (borrow == ty::BorrowKind::UniqueImmBorrow && base_ty.ref_mutability() == Some(Mutability::Mut)) + { + self.add_mutably_used_var(*vid); + } + } + } + + fn mutate(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, _id: HirId) { + self.prev_bind = None; + if let euv::Place { + projections, + base: euv::PlaceBase::Local(vid), + .. + } = &cmt.place + { + if !projections.is_empty() { + self.add_mutably_used_var(*vid); + } + } + } + + fn copy(&mut self, _cmt: &euv::PlaceWithHirId<'tcx>, _id: HirId) { + self.prev_bind = None; + } + + fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {} + + fn bind(&mut self, _cmt: &euv::PlaceWithHirId<'tcx>, id: HirId) { + self.prev_bind = Some(id); + } +} diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 327e090d38be..912798db76a9 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -7,18 +7,17 @@ use clippy_utils::ty::{ use clippy_utils::{get_trait_def_id, is_self, paths}; use if_chain::if_chain; use rustc_ast::ast::Attribute; -use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, Diagnostic}; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Mutability, Node, PatKind, QPath, TyKind, + BindingAnnotation, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, PatKind, + QPath, TyKind, }; -use rustc_hir::{HirIdMap, HirIdSet, LangItem}; use rustc_hir_typeck::expr_use_visitor as euv; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; -use rustc_middle::ty::{self, TypeVisitableExt}; +use rustc_middle::ty::{self, TypeVisitableExt, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; @@ -26,7 +25,6 @@ use rustc_span::{sym, Span}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits; use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy; -use std::borrow::Cow; declare_clippy_lint! { /// ### What it does @@ -122,14 +120,12 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { let sized_trait = need!(cx.tcx.lang_items().sized_trait()); - let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds().iter()) + let preds = traits::elaborate(cx.tcx, cx.param_env.caller_bounds().iter()) .filter(|p| !p.is_global()) .filter_map(|pred| { // Note that we do not want to deal with qualified predicates here. match pred.kind().no_bound_vars() { - Some(ty::PredicateKind::Clause(ty::Clause::Trait(pred))) if pred.def_id() != sized_trait => { - Some(pred) - }, + Some(ty::ClauseKind::Trait(pred)) if pred.def_id() != sized_trait => Some(pred), _ => None, } }) @@ -137,11 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { // Collect moved variables and spans which will need dereferencings from the // function body. - let MovedVariablesCtxt { - moved_vars, - spans_need_deref, - .. - } = { + let MovedVariablesCtxt { moved_vars } = { let mut ctx = MovedVariablesCtxt::default(); let infcx = cx.tcx.infer_ctxt().build(); euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body); @@ -176,7 +168,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { ( preds.iter().any(|t| cx.tcx.is_diagnostic_item(sym::Borrow, t.def_id())), !preds.is_empty() && { - let ty_empty_region = cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_erased, ty); + let ty_empty_region = Ty::new_imm_ref(cx.tcx,cx.tcx.lifetimes.re_erased, ty); preds.iter().all(|t| { let ty_params = t.trait_ref.substs.iter().skip(1).collect::>(); implements_trait(cx, ty_empty_region, t.def_id(), &ty_params) @@ -212,7 +204,6 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { } } - let deref_span = spans_need_deref.get(&canonical_id); if_chain! { if is_type_diagnostic_item(cx, ty, sym::Vec); if let Some(clone_spans) = @@ -240,16 +231,14 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { snippet_opt(cx, span) .map_or( "change the call to".into(), - |x| Cow::from(format!("change `{x}` to")), - ) - .as_ref(), + |x| format!("change `{x}` to"), + ), suggestion, Applicability::Unspecified, ); } // cannot be destructured, no need for `*` suggestion - assert!(deref_span.is_none()); return; } } @@ -270,31 +259,19 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { snippet_opt(cx, span) .map_or( "change the call to".into(), - |x| Cow::from(format!("change `{x}` to")) - ) - .as_ref(), + |x| format!("change `{x}` to") + ), suggestion, Applicability::Unspecified, ); } - assert!(deref_span.is_none()); return; } } - let mut spans = vec![(input.span, format!("&{}", snippet(cx, input.span, "_")))]; - - // Suggests adding `*` to dereference the added reference. - if let Some(deref_span) = deref_span { - spans.extend( - deref_span - .iter() - .copied() - .map(|span| (span, format!("*{}", snippet(cx, span, "")))), - ); - spans.sort_by_key(|&(span, _)| span); - } + let spans = vec![(input.span, format!("&{}", snippet(cx, input.span, "_")))]; + multispan_sugg(diag, "consider taking a reference instead", spans); }; @@ -312,7 +289,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { } /// Functions marked with these attributes must have the exact signature. -fn requires_exact_signature(attrs: &[Attribute]) -> bool { +pub(crate) fn requires_exact_signature(attrs: &[Attribute]) -> bool { attrs.iter().any(|attr| { [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive] .iter() @@ -323,9 +300,6 @@ fn requires_exact_signature(attrs: &[Attribute]) -> bool { #[derive(Default)] struct MovedVariablesCtxt { moved_vars: HirIdSet, - /// Spans which need to be prefixed with `*` for dereferencing the - /// suggested additional reference. - spans_need_deref: HirIdMap>, } impl MovedVariablesCtxt { diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index e3712190e672..e6d3e72d1e62 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -1,11 +1,15 @@ use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then}; -use clippy_utils::is_lint_allowed; -use clippy_utils::peel_blocks; use clippy_utils::source::snippet_opt; use clippy_utils::ty::has_drop; +use clippy_utils::{get_parent_node, is_lint_allowed, peel_blocks}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, PatKind, Stmt, StmtKind, UnsafeSource}; +use rustc_hir::{ + is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, FnRetTy, ItemKind, Node, PatKind, Stmt, StmtKind, + UnsafeSource, +}; +use rustc_hir_analysis::hir_ty_to_ty; +use rustc_infer::infer::TyCtxtInferExt as _; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -86,7 +90,43 @@ impl<'tcx> LateLintPass<'tcx> for NoEffect { fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool { if let StmtKind::Semi(expr) = stmt.kind { if has_no_effect(cx, expr) { - span_lint_hir(cx, NO_EFFECT, expr.hir_id, stmt.span, "statement with no effect"); + span_lint_hir_and_then( + cx, + NO_EFFECT, + expr.hir_id, + stmt.span, + "statement with no effect", + |diag| { + for parent in cx.tcx.hir().parent_iter(stmt.hir_id) { + if let Node::Item(item) = parent.1 + && let ItemKind::Fn(sig, ..) = item.kind + && let FnRetTy::Return(ret_ty) = sig.decl.output + && let Some(Node::Block(block)) = get_parent_node(cx.tcx, stmt.hir_id) + && let [.., final_stmt] = block.stmts + && final_stmt.hir_id == stmt.hir_id + { + let expr_ty = cx.typeck_results().expr_ty(expr); + let mut ret_ty = hir_ty_to_ty(cx.tcx, ret_ty); + + // Remove `impl Future` to get `T` + if cx.tcx.ty_is_opaque_future(ret_ty) && + let Some(true_ret_ty) = cx.tcx.infer_ctxt().build().get_impl_future_output_ty(ret_ty) + { + ret_ty = true_ret_ty; + } + + if ret_ty == expr_ty { + diag.span_suggestion( + stmt.span.shrink_to_lo(), + "did you mean to return it?", + "return ", + Applicability::MaybeIncorrect, + ); + } + } + } + }, + ); return true; } } else if let StmtKind::Local(local) = stmt.kind { diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 9ab6743d3694..850254c7641a 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -15,12 +15,14 @@ use rustc_hir::{ }; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::{LateContext, LateLintPass, Lint}; -use rustc_middle::mir; -use rustc_middle::mir::interpret::{ConstValue, ErrorHandled}; +use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::adjustment::Adjust; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{sym, InnerSpan, Span}; +use rustc_target::abi::VariantIdx; +use rustc_middle::mir::interpret::EvalToValTreeResult; +use rustc_middle::mir::interpret::GlobalId; // FIXME: this is a correctness problem but there's no suitable // warn-by-default category. @@ -141,21 +143,35 @@ fn is_unfrozen<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { fn is_value_unfrozen_raw<'tcx>( cx: &LateContext<'tcx>, - result: Result, ErrorHandled>, + result: Result>, ErrorHandled>, ty: Ty<'tcx>, ) -> bool { - fn inner<'tcx>(cx: &LateContext<'tcx>, val: mir::ConstantKind<'tcx>) -> bool { - match val.ty().kind() { + fn inner<'tcx>(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool { + match *ty.kind() { // the fact that we have to dig into every structs to search enums // leads us to the point checking `UnsafeCell` directly is the only option. ty::Adt(ty_def, ..) if ty_def.is_unsafe_cell() => true, // As of 2022-09-08 miri doesn't track which union field is active so there's no safe way to check the // contained value. ty::Adt(def, ..) if def.is_union() => false, - ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => { - let val = cx.tcx.destructure_mir_constant(cx.param_env, val); - val.fields.iter().any(|field| inner(cx, *field)) + ty::Array(ty, _) => { + val.unwrap_branch().iter().any(|field| inner(cx, *field, ty)) }, + ty::Adt(def, _) if def.is_union() => false, + ty::Adt(def, substs) if def.is_enum() => { + let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap(); + let variant_index = + VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap()); + fields.iter().copied().zip( + def.variants()[variant_index] + .fields + .iter() + .map(|field| field.ty(cx.tcx, substs))).any(|(field, ty)| inner(cx, field, ty)) + } + ty::Adt(def, substs) => { + val.unwrap_branch().iter().zip(def.non_enum_variant().fields.iter().map(|field| field.ty(cx.tcx, substs))).any(|(field, ty)| inner(cx, *field, ty)) + } + ty::Tuple(tys) => val.unwrap_branch().iter().zip(tys).any(|(field, ty)| inner(cx, *field, ty)), _ => false, } } @@ -166,15 +182,15 @@ fn is_value_unfrozen_raw<'tcx>( // have a value that is a frozen variant with a generic param (an example is // `declare_interior_mutable_const::enums::BothOfCellAndGeneric::GENERIC_VARIANT`). // However, it prevents a number of false negatives that is, I think, important: - // 1. assoc consts in trait defs referring to consts of themselves - // (an example is `declare_interior_mutable_const::traits::ConcreteTypes::ANOTHER_ATOMIC`). - // 2. a path expr referring to assoc consts whose type is doesn't have - // any frozen variants in trait defs (i.e. without substitute for `Self`). - // (e.g. borrowing `borrow_interior_mutable_const::trait::ConcreteTypes::ATOMIC`) - // 3. similar to the false positive above; - // but the value is an unfrozen variant, or the type has no enums. (An example is - // `declare_interior_mutable_const::enums::BothOfCellAndGeneric::UNFROZEN_VARIANT` - // and `declare_interior_mutable_const::enums::BothOfCellAndGeneric::NO_ENUM`). + // 1. assoc consts in trait defs referring to consts of themselves (an example is + // `declare_interior_mutable_const::traits::ConcreteTypes::ANOTHER_ATOMIC`). + // 2. a path expr referring to assoc consts whose type is doesn't have any frozen variants in trait + // defs (i.e. without substitute for `Self`). (e.g. borrowing + // `borrow_interior_mutable_const::trait::ConcreteTypes::ATOMIC`) + // 3. similar to the false positive above; but the value is an unfrozen variant, or the type has no + // enums. (An example is + // `declare_interior_mutable_const::enums::BothOfCellAndGeneric::UNFROZEN_VARIANT` and + // `declare_interior_mutable_const::enums::BothOfCellAndGeneric::NO_ENUM`). // One might be able to prevent these FNs correctly, and replace this with `false`; // e.g. implementing `has_frozen_variant` described above, and not running this function // when the type doesn't have any frozen variants would be the 'correct' way for the 2nd @@ -184,26 +200,50 @@ fn is_value_unfrozen_raw<'tcx>( // I chose this way because unfrozen enums as assoc consts are rare (or, hopefully, none). err == ErrorHandled::TooGeneric }, - |val| inner(cx, mir::ConstantKind::from_value(val, ty)), + |val| val.map_or(true, |val| inner(cx, val, ty)), ) } fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool { - let result = cx.tcx.const_eval_poly(body_id.hir_id.owner.to_def_id()); + let def_id = body_id.hir_id.owner.to_def_id(); + let substs = ty::InternalSubsts::identity_for_item(cx.tcx, def_id); + let instance = ty::Instance::new(def_id, substs); + let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None }; + let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx); + let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, None); is_value_unfrozen_raw(cx, result, ty) } fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool { let substs = cx.typeck_results().node_substs(hir_id); - let result = cx.tcx.const_eval_resolve( - cx.param_env, - mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs), - None, - ); +<<<<<<< HEAD + let result = const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, substs), None); +======= + let result = cx + .tcx + .const_eval_resolve(cx.param_env, mir::UnevaluatedConst::new(def_id, substs), None); +>>>>>>> e4f5d83fa (Fixed formatting.) is_value_unfrozen_raw(cx, result, ty) } + +pub fn const_eval_resolve<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ct: ty::UnevaluatedConst<'tcx>, + span: Option, +) -> EvalToValTreeResult<'tcx> { + match ty::Instance::resolve(tcx, param_env, ct.def, ct.substs) { + Ok(Some(instance)) => { + let cid = GlobalId { instance, promoted: None }; + tcx.const_eval_global_id_for_typeck(param_env, cid, span) + } + Ok(None) => Err(ErrorHandled::TooGeneric), + Err(err) => Err(ErrorHandled::Reported(err.into())), + } +} + #[derive(Copy, Clone)] enum Source { Item { item: Span }, diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs index 9f6917c146f6..d562047cbf15 100644 --- a/clippy_lints/src/non_expressive_names.rs +++ b/clippy_lints/src/non_expressive_names.rs @@ -91,7 +91,7 @@ struct ExistingName { struct SimilarNamesLocalVisitor<'a, 'tcx> { names: Vec, cx: &'a EarlyContext<'tcx>, - lint: &'a NonExpressiveNames, + lint: NonExpressiveNames, /// A stack of scopes containing the single-character bindings in each scope. single_char_names: Vec>, @@ -365,7 +365,7 @@ impl EarlyLintPass for NonExpressiveNames { .. }) = item.kind { - do_check(self, cx, &item.attrs, &sig.decl, blk); + do_check(*self, cx, &item.attrs, &sig.decl, blk); } } @@ -380,12 +380,12 @@ impl EarlyLintPass for NonExpressiveNames { .. }) = item.kind { - do_check(self, cx, &item.attrs, &sig.decl, blk); + do_check(*self, cx, &item.attrs, &sig.decl, blk); } } } -fn do_check(lint: &mut NonExpressiveNames, cx: &EarlyContext<'_>, attrs: &[Attribute], decl: &FnDecl, blk: &Block) { +fn do_check(lint: NonExpressiveNames, cx: &EarlyContext<'_>, attrs: &[Attribute], decl: &FnDecl, blk: &Block) { if !attrs.iter().any(|attr| attr.has_name(sym::test)) { let mut visitor = SimilarNamesLocalVisitor { names: Vec::new(), diff --git a/clippy_lints/src/non_send_fields_in_send_ty.rs b/clippy_lints/src/non_send_fields_in_send_ty.rs index 839c3a3815c2..24875855de34 100644 --- a/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -7,7 +7,8 @@ use rustc_hir::def_id::DefId; use rustc_hir::{FieldDef, Item, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, subst::GenericArgKind, Ty}; +use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::sym; @@ -131,13 +132,13 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy { for field in non_send_fields { diag.span_note( field.def.span, - &format!("it is not safe to send field `{}` to another thread", field.def.ident.name), + format!("it is not safe to send field `{}` to another thread", field.def.ident.name), ); match field.generic_params.len() { 0 => diag.help("use a thread-safe type that implements `Send`"), - 1 if is_ty_param(field.ty) => diag.help(&format!("add `{}: Send` bound in `Send` impl", field.ty)), - _ => diag.help(&format!( + 1 if is_ty_param(field.ty) => diag.help(format!("add `{}: Send` bound in `Send` impl", field.ty)), + _ => diag.help(format!( "add bounds on type parameter{} `{}` that satisfy `{}: Send`", if field.generic_params.len() > 1 { "s" } else { "" }, field.generic_params_string(), diff --git a/clippy_lints/src/nonstandard_macro_braces.rs b/clippy_lints/src/nonstandard_macro_braces.rs index 6c909e5ed73e..bd194b93584e 100644 --- a/clippy_lints/src/nonstandard_macro_braces.rs +++ b/clippy_lints/src/nonstandard_macro_braces.rs @@ -1,7 +1,5 @@ -use std::{ - fmt, - hash::{Hash, Hasher}, -}; +use std::fmt; +use std::hash::{Hash, Hasher}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_opt; @@ -241,7 +239,7 @@ impl<'de> Deserialize<'de> for MacroMatcher { V: de::MapAccess<'de>, { let mut name = None; - let mut brace: Option<&str> = None; + let mut brace: Option = None; while let Some(key) = map.next_key()? { match key { Field::Name => { diff --git a/clippy_lints/src/operators/absurd_extreme_comparisons.rs b/clippy_lints/src/operators/absurd_extreme_comparisons.rs index d29ca37eaeb8..f4863600ccc0 100644 --- a/clippy_lints/src/operators/absurd_extreme_comparisons.rs +++ b/clippy_lints/src/operators/absurd_extreme_comparisons.rs @@ -121,7 +121,7 @@ fn detect_absurd_comparison<'tcx>( fn detect_extreme_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option> { let ty = cx.typeck_results().expr_ty(expr); - let cv = constant(cx, cx.typeck_results(), expr)?.0; + let cv = constant(cx, cx.typeck_results(), expr)?; let which = match (ty.kind(), cv) { (&ty::Bool, Constant::Bool(false)) | (&ty::Uint(_), Constant::Int(0)) => ExtremeType::Minimum, diff --git a/clippy_lints/src/operators/arithmetic_side_effects.rs b/clippy_lints/src/operators/arithmetic_side_effects.rs index e5713735672d..ac6d84200dff 100644 --- a/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -1,25 +1,46 @@ use super::ARITHMETIC_SIDE_EFFECTS; +<<<<<<< HEAD +use clippy_utils::consts::{constant, constant_simple, Constant}; +use clippy_utils::diagnostics::span_lint; +use clippy_utils::{is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary}; +======= +use clippy_utils::is_from_proc_macro; use clippy_utils::{ consts::{constant, constant_simple, Constant}, diagnostics::span_lint, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary, }; use rustc_ast as ast; +>>>>>>> e4f5d83fa (Fixed formatting.) use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; use rustc_session::impl_lint_pass; +<<<<<<< HEAD use rustc_span::source_map::{Span, Spanned}; +use rustc_span::Symbol; +use {rustc_ast as ast, rustc_hir as hir}; +======= +use rustc_span::{ + source_map::{Span, Spanned}, + Symbol, +}; +>>>>>>> e4f5d83fa (Fixed formatting.) const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[ ["f32", "f32"], ["f64", "f64"], +<<<<<<< HEAD + ["std::num::Saturating", "*"], + ["std::num::Wrapping", "*"], +======= ["std::num::Saturating", "std::num::Saturating"], ["std::num::Wrapping", "std::num::Wrapping"], - ["std::string::String", "&str"], +>>>>>>> e4f5d83fa (Fixed formatting.) + ["std::string::String", "str"], ]; const HARD_CODED_ALLOWED_UNARY: &[&str] = &["f32", "f64", "std::num::Saturating", "std::num::Wrapping"]; +const INTEGER_METHODS: &[&str] = &["saturating_div", "wrapping_div", "wrapping_rem", "wrapping_rem_euclid"]; #[derive(Debug)] pub struct ArithmeticSideEffects { @@ -28,6 +49,7 @@ pub struct ArithmeticSideEffects { // Used to check whether expressions are constants, such as in enum discriminants and consts const_span: Option, expr_span: Option, + integer_methods: FxHashSet, } impl_lint_pass!(ArithmeticSideEffects => [ARITHMETIC_SIDE_EFFECTS]); @@ -53,6 +75,7 @@ impl ArithmeticSideEffects { allowed_unary, const_span: None, expr_span: None, + integer_methods: INTEGER_METHODS.iter().map(|el| Symbol::intern(el)).collect(), } } @@ -106,7 +129,7 @@ impl ArithmeticSideEffects { if let hir::ExprKind::Lit(ref lit) = actual.kind && let ast::LitKind::Int(n, _) = lit.node { return Some(n) } - if let Some((Constant::Int(n), _)) = constant(cx, cx.typeck_results(), expr) { + if let Some(Constant::Int(n)) = constant(cx, cx.typeck_results(), expr) { return Some(n); } None @@ -137,8 +160,10 @@ impl ArithmeticSideEffects { ) { return; }; - let lhs_ty = cx.typeck_results().expr_ty(lhs); - let rhs_ty = cx.typeck_results().expr_ty(rhs); + let (actual_lhs, lhs_ref_counter) = peel_hir_expr_refs(lhs); + let (actual_rhs, rhs_ref_counter) = peel_hir_expr_refs(rhs); + let lhs_ty = cx.typeck_results().expr_ty(actual_lhs).peel_refs(); + let rhs_ty = cx.typeck_results().expr_ty(actual_rhs).peel_refs(); if self.has_allowed_binary(lhs_ty, rhs_ty) { return; } @@ -147,8 +172,6 @@ impl ArithmeticSideEffects { // At least for integers, shifts are already handled by the CTFE return; } - let (actual_lhs, lhs_ref_counter) = peel_hir_expr_refs(lhs); - let (actual_rhs, rhs_ref_counter) = peel_hir_expr_refs(rhs); match ( Self::literal_integer(cx, actual_lhs), Self::literal_integer(cx, actual_rhs), @@ -184,6 +207,91 @@ impl ArithmeticSideEffects { } } + /// There are some integer methods like `wrapping_div` that will panic depending on the + /// provided input. + fn manage_method_call<'tcx>( + &mut self, + args: &[hir::Expr<'tcx>], + cx: &LateContext<'tcx>, + ps: &hir::PathSegment<'tcx>, + receiver: &hir::Expr<'tcx>, + ) { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +<<<<<<< HEAD +<<<<<<< HEAD +======= + const METHODS: &[&str] = &["saturating_div", "wrapping_div", "wrapping_rem", "wrapping_rem_euclid"]; +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> 0b16f80c4 ([arithmetic_side_effects] Cache symbols) +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + const METHODS: &[&str] = &["saturating_div", "wrapping_div", "wrapping_rem", "wrapping_rem_euclid"]; +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> 0b16f80c4 ([arithmetic_side_effects] Cache symbols) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + let Some(arg) = args.first() else { return; }; + if constant_simple(cx, cx.typeck_results(), receiver).is_some() { + return; + } + let instance_ty = cx.typeck_results().expr_ty(receiver); + if !Self::is_integral(instance_ty) { + return; + } +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if !self.integer_methods.contains(&ps.ident.name) { +======= +======= + if !self.integer_methods.contains(&ps.ident.name) { +======= +<<<<<<< HEAD +<<<<<<< HEAD + if !self.integer_methods.contains(&ps.ident.name) { +======= +>>>>>>> 4da6e7e06 (rebase attempt) + if METHODS.iter().copied().all(|method| method != ps.ident.as_str()) { +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= + if !self.integer_methods.contains(&ps.ident.name) { +>>>>>>> 0b16f80c4 ([arithmetic_side_effects] Cache symbols) +<<<<<<< HEAD +======= + if !self.integer_methods.contains(&ps.ident.name) { +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + if METHODS.iter().copied().all(|method| method != ps.ident.as_str()) { +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= + if !self.integer_methods.contains(&ps.ident.name) { +>>>>>>> 0b16f80c4 ([arithmetic_side_effects] Cache symbols) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + return; + } + let (actual_arg, _) = peel_hir_expr_refs(arg); + match Self::literal_integer(cx, actual_arg) { + None | Some(0) => self.issue_lint(cx, arg), + Some(_) => {}, + } + } + fn manage_unary_ops<'tcx>( &mut self, cx: &LateContext<'tcx>, @@ -206,8 +314,9 @@ impl ArithmeticSideEffects { self.issue_lint(cx, expr); } - fn should_skip_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { + fn should_skip_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) -> bool { is_lint_allowed(cx, ARITHMETIC_SIDE_EFFECTS, expr.hir_id) + || is_from_proc_macro(cx, expr) || self.expr_span.is_some() || self.const_span.map_or(false, |sp| sp.contains(expr.span)) } @@ -222,6 +331,9 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects { hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => { self.manage_bin_ops(cx, expr, op, lhs, rhs); }, + hir::ExprKind::MethodCall(ps, receiver, args, _) => { + self.manage_method_call(args, cx, ps, receiver); + }, hir::ExprKind::Unary(un_op, un_expr) => { self.manage_unary_ops(cx, expr, un_expr, *un_op); }, diff --git a/clippy_lints/src/operators/assign_op_pattern.rs b/clippy_lints/src/operators/assign_op_pattern.rs index 9bbf385fb599..c4572a09db61 100644 --- a/clippy_lints/src/operators/assign_op_pattern.rs +++ b/clippy_lints/src/operators/assign_op_pattern.rs @@ -1,9 +1,8 @@ -use clippy_utils::binop_traits; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_opt; use clippy_utils::ty::implements_trait; use clippy_utils::visitors::for_each_expr; -use clippy_utils::{eq_expr_value, trait_ref_of_method}; +use clippy_utils::{binop_traits, eq_expr_value, trait_ref_of_method}; use core::ops::ControlFlow; use if_chain::if_chain; use rustc_errors::Applicability; diff --git a/clippy_lints/src/operators/bit_mask.rs b/clippy_lints/src/operators/bit_mask.rs index 1369b3e74625..1fddf0f50e32 100644 --- a/clippy_lints/src/operators/bit_mask.rs +++ b/clippy_lints/src/operators/bit_mask.rs @@ -166,7 +166,7 @@ fn check_ineffective_gt(cx: &LateContext<'_>, span: Span, m: u128, c: u128, op: } fn fetch_int_literal(cx: &LateContext<'_>, lit: &Expr<'_>) -> Option { - match constant(cx, cx.typeck_results(), lit)?.0 { + match constant(cx, cx.typeck_results(), lit)? { Constant::Int(n) => Some(n), _ => None, } diff --git a/clippy_lints/src/operators/cmp_nan.rs b/clippy_lints/src/operators/cmp_nan.rs index 786ae1552ad3..e18064b7061b 100644 --- a/clippy_lints/src/operators/cmp_nan.rs +++ b/clippy_lints/src/operators/cmp_nan.rs @@ -18,7 +18,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, op: BinOpKind, lhs: &Exp } fn is_nan(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - if let Some((value, _)) = constant(cx, cx.typeck_results(), e) { + if let Some(value) = constant(cx, cx.typeck_results(), e) { match value { Constant::F32(num) => num.is_nan(), Constant::F64(num) => num.is_nan(), diff --git a/clippy_lints/src/operators/duration_subsec.rs b/clippy_lints/src/operators/duration_subsec.rs index 49e662cacb0c..f120be13836d 100644 --- a/clippy_lints/src/operators/duration_subsec.rs +++ b/clippy_lints/src/operators/duration_subsec.rs @@ -19,7 +19,7 @@ pub(crate) fn check<'tcx>( if op == BinOpKind::Div && let ExprKind::MethodCall(method_path, self_arg, [], _) = left.kind && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_arg).peel_refs(), sym::Duration) - && let Some((Constant::Int(divisor), _)) = constant(cx, cx.typeck_results(), right) + && let Some(Constant::Int(divisor)) = constant(cx, cx.typeck_results(), right) { let suggested_fn = match (method_path.ident.as_str(), divisor) { ("subsec_micros", 1_000) | ("subsec_nanos", 1_000_000) => "subsec_millis", diff --git a/clippy_lints/src/operators/eq_op.rs b/clippy_lints/src/operators/eq_op.rs index 67913f7392c0..88d566318414 100644 --- a/clippy_lints/src/operators/eq_op.rs +++ b/clippy_lints/src/operators/eq_op.rs @@ -1,6 +1,7 @@ -use clippy_utils::diagnostics::span_lint; +use clippy_utils::ast_utils::is_useless_with_eq_exprs; +use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; use clippy_utils::macros::{find_assert_eq_args, first_node_macro_backtrace}; -use clippy_utils::{ast_utils::is_useless_with_eq_exprs, eq_expr_value, is_in_test_function}; +use clippy_utils::{eq_expr_value, is_in_test_function}; use rustc_hir::{BinOpKind, Expr}; use rustc_lint::LateContext; @@ -35,11 +36,16 @@ pub(crate) fn check<'tcx>( right: &'tcx Expr<'_>, ) { if is_useless_with_eq_exprs(op.into()) && eq_expr_value(cx, left, right) && !is_in_test_function(cx.tcx, e.hir_id) { - span_lint( + span_lint_and_then( cx, EQ_OP, e.span, &format!("equal expressions as operands to `{}`", op.as_str()), + |diag| { + if let BinOpKind::Ne = op && cx.typeck_results().expr_ty(left).is_floating_point() { + diag.note("if you intended to check if the operand is NaN, use `.is_nan()` instead"); + } + }, ); } } diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index 97ddcdb24799..90263dcece68 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -1,4 +1,4 @@ -use clippy_utils::consts::{constant, Constant}; +use clippy_utils::consts::{constant_with_source, Constant}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::get_item_name; use clippy_utils::sugg::Sugg; @@ -18,9 +18,16 @@ pub(crate) fn check<'tcx>( right: &'tcx Expr<'_>, ) { if (op == BinOpKind::Eq || op == BinOpKind::Ne) && (is_float(cx, left) || is_float(cx, right)) { - if is_allowed(cx, left) || is_allowed(cx, right) { - return; - } + let left_is_local = match constant_with_source(cx, cx.typeck_results(), left) { + Some((c, s)) if !is_allowed(&c) => s.is_local(), + Some(_) => return, + None => true, + }; + let right_is_local = match constant_with_source(cx, cx.typeck_results(), right) { + Some((c, s)) if !is_allowed(&c) => s.is_local(), + Some(_) => return, + None => true, + }; // Allow comparing the results of signum() if is_signum(cx, left) && is_signum(cx, right) { @@ -34,10 +41,7 @@ pub(crate) fn check<'tcx>( } } let is_comparing_arrays = is_array(cx, left) || is_array(cx, right); - let (lint, msg) = get_lint_and_message( - is_named_constant(cx, left) || is_named_constant(cx, right), - is_comparing_arrays, - ); + let (lint, msg) = get_lint_and_message(left_is_local && right_is_local, is_comparing_arrays); span_lint_and_then(cx, lint, expr.span, msg, |diag| { let lhs = Sugg::hir(cx, left, ".."); let rhs = Sugg::hir(cx, right, ".."); @@ -59,44 +63,41 @@ pub(crate) fn check<'tcx>( } } -fn get_lint_and_message( - is_comparing_constants: bool, - is_comparing_arrays: bool, -) -> (&'static rustc_lint::Lint, &'static str) { - if is_comparing_constants { +fn get_lint_and_message(is_local: bool, is_comparing_arrays: bool) -> (&'static rustc_lint::Lint, &'static str) { + if is_local { ( - FLOAT_CMP_CONST, + FLOAT_CMP, if is_comparing_arrays { - "strict comparison of `f32` or `f64` constant arrays" + "strict comparison of `f32` or `f64` arrays" } else { - "strict comparison of `f32` or `f64` constant" + "strict comparison of `f32` or `f64`" }, ) } else { ( - FLOAT_CMP, + FLOAT_CMP_CONST, if is_comparing_arrays { - "strict comparison of `f32` or `f64` arrays" + "strict comparison of `f32` or `f64` constant arrays" } else { - "strict comparison of `f32` or `f64`" + "strict comparison of `f32` or `f64` constant" }, ) } } -fn is_named_constant<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool { - if let Some((_, res)) = constant(cx, cx.typeck_results(), expr) { - res - } else { - false - } -} - -fn is_allowed<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool { - match constant(cx, cx.typeck_results(), expr) { - Some((Constant::F32(f), _)) => f == 0.0 || f.is_infinite(), - Some((Constant::F64(f), _)) => f == 0.0 || f.is_infinite(), - Some((Constant::Vec(vec), _)) => vec.iter().all(|f| match f { +<<<<<<< HEAD +<<<<<<< HEAD +fn is_allowed(val: &Constant<'_>) -> bool { +======= +fn is_allowed(val: &Constant) -> bool { +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) +======= +fn is_allowed(val: &Constant<'_>) -> bool { +>>>>>>> 0e1caa765 (Fix #10792) + match val { + &Constant::F32(f) => f == 0.0 || f.is_infinite(), + &Constant::F64(f) => f == 0.0 || f.is_infinite(), + Constant::Vec(vec) => vec.iter().all(|f| match f { Constant::F32(f) => *f == 0.0 || (*f).is_infinite(), Constant::F64(f) => *f == 0.0 || (*f).is_infinite(), _ => false, diff --git a/clippy_lints/src/operators/misrefactored_assign_op.rs b/clippy_lints/src/operators/misrefactored_assign_op.rs index 015f6c14e761..5eabb349ec10 100644 --- a/clippy_lints/src/operators/misrefactored_assign_op.rs +++ b/clippy_lints/src/operators/misrefactored_assign_op.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::eq_expr_value; use clippy_utils::source::snippet_opt; -use clippy_utils::sugg; +use clippy_utils::{eq_expr_value, sugg}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 19599731bd6e..2cf15adda01a 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -1,7 +1,6 @@ mod absurd_extreme_comparisons; mod assign_op_pattern; mod bit_mask; -mod cmp_nan; mod cmp_owned; mod double_comparison; mod duration_subsec; @@ -96,32 +95,6 @@ declare_clippy_lint! { "any arithmetic expression that can cause side effects like overflows or panics" } -declare_clippy_lint! { - /// ### What it does - /// Checks for integer arithmetic operations which could overflow or panic. - /// - /// Specifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable - /// of overflowing according to the [Rust - /// Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow), - /// or which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is - /// attempted. - /// - /// ### Why is this bad? - /// Integer overflow will trigger a panic in debug builds or will wrap in - /// release mode. Division by zero will cause a panic in either mode. In some applications one - /// wants explicitly checked, wrapping or saturating arithmetic. - /// - /// ### Example - /// ```rust - /// # let a = 0; - /// a + 1; - /// ``` - #[clippy::version = "pre 1.29.0"] - pub INTEGER_ARITHMETIC, - restriction, - "any integer arithmetic expression which could overflow or panic" -} - declare_clippy_lint! { /// ### What it does /// Checks for float arithmetic. @@ -511,31 +484,6 @@ declare_clippy_lint! { "integer division may cause loss of precision" } -declare_clippy_lint! { - /// ### What it does - /// Checks for comparisons to NaN. - /// - /// ### Why is this bad? - /// NaN does not compare meaningfully to anything – not - /// even itself – so those comparisons are simply wrong. - /// - /// ### Example - /// ```rust - /// # let x = 1.0; - /// if x == f32::NAN { } - /// ``` - /// - /// Use instead: - /// ```rust - /// # let x = 1.0f32; - /// if x.is_nan() { } - /// ``` - #[clippy::version = "pre 1.29.0"] - pub CMP_NAN, - correctness, - "comparisons to `NAN`, which will always return false, probably not intended" -} - declare_clippy_lint! { /// ### What it does /// Checks for conversions to owned values just for the sake @@ -787,7 +735,6 @@ pub struct Operators { impl_lint_pass!(Operators => [ ABSURD_EXTREME_COMPARISONS, ARITHMETIC_SIDE_EFFECTS, - INTEGER_ARITHMETIC, FLOAT_ARITHMETIC, ASSIGN_OP_PATTERN, MISREFACTORED_ASSIGN_OP, @@ -802,7 +749,6 @@ impl_lint_pass!(Operators => [ FLOAT_EQUALITY_WITHOUT_ABS, IDENTITY_OP, INTEGER_DIVISION, - CMP_NAN, CMP_OWNED, FLOAT_CMP, FLOAT_CMP_CONST, @@ -843,7 +789,6 @@ impl<'tcx> LateLintPass<'tcx> for Operators { duration_subsec::check(cx, e, op.node, lhs, rhs); float_equality_without_abs::check(cx, e, op.node, lhs, rhs); integer_division::check(cx, e, op.node, lhs, rhs); - cmp_nan::check(cx, e, op.node, lhs, rhs); cmp_owned::check(cx, op.node, lhs, rhs); float_cmp::check(cx, e, op.node, lhs, rhs); modulo_one::check(cx, e, op.node, rhs); diff --git a/clippy_lints/src/operators/modulo_arithmetic.rs b/clippy_lints/src/operators/modulo_arithmetic.rs index af4e74947f41..a2c3a4d8ba77 100644 --- a/clippy_lints/src/operators/modulo_arithmetic.rs +++ b/clippy_lints/src/operators/modulo_arithmetic.rs @@ -40,7 +40,7 @@ struct OperandInfo { fn analyze_operand(operand: &Expr<'_>, cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { match constant(cx, cx.typeck_results(), operand) { - Some((Constant::Int(v), _)) => match *cx.typeck_results().expr_ty(expr).kind() { + Some(Constant::Int(v)) => match *cx.typeck_results().expr_ty(expr).kind() { ty::Int(ity) => { let value = sext(cx.tcx, v, ity); return Some(OperandInfo { @@ -58,10 +58,10 @@ fn analyze_operand(operand: &Expr<'_>, cx: &LateContext<'_>, expr: &Expr<'_>) -> }, _ => {}, }, - Some((Constant::F32(f), _)) => { + Some(Constant::F32(f)) => { return Some(floating_point_operand_info(&f)); }, - Some((Constant::F64(f), _)) => { + Some(Constant::F64(f)) => { return Some(floating_point_operand_info(&f)); }, _ => {}, diff --git a/clippy_lints/src/operators/numeric_arithmetic.rs b/clippy_lints/src/operators/numeric_arithmetic.rs index 777395f452c9..7dbe1ef3dd97 100644 --- a/clippy_lints/src/operators/numeric_arithmetic.rs +++ b/clippy_lints/src/operators/numeric_arithmetic.rs @@ -1,12 +1,18 @@ +<<<<<<< HEAD +use super::FLOAT_ARITHMETIC; use clippy_utils::consts::constant_simple; use clippy_utils::diagnostics::span_lint; +======= +use super::{FLOAT_ARITHMETIC, INTEGER_ARITHMETIC}; +use clippy_utils::consts::constant_simple; +use clippy_utils::diagnostics::span_lint; +use clippy_utils::is_from_proc_macro; use clippy_utils::is_integer_literal; +>>>>>>> e4f5d83fa (Fixed formatting.) use rustc_hir as hir; use rustc_lint::LateContext; use rustc_span::source_map::Span; -use super::{FLOAT_ARITHMETIC, INTEGER_ARITHMETIC}; - #[derive(Default)] pub struct Context { expr_id: Option, @@ -45,8 +51,33 @@ impl Context { _ => (), } +<<<<<<< HEAD +<<<<<<< HEAD let (l_ty, r_ty) = (cx.typeck_results().expr_ty(l), cx.typeck_results().expr_ty(r)); if l_ty.peel_refs().is_integral() && r_ty.peel_refs().is_integral() { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if is_from_proc_macro(cx, expr) { +======= + if Self::skip_expr_involving_integers(cx, expr) { +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + if is_from_proc_macro(cx, expr) { +>>>>>>> d6390625d (Address comments) +======= + if is_from_proc_macro(cx, expr) { +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + if Self::skip_expr_involving_integers(cx, expr) { +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + if is_from_proc_macro(cx, expr) { +>>>>>>> d6390625d (Address comments) + return; + } match op { hir::BinOpKind::Div | hir::BinOpKind::Rem => match &r.kind { hir::ExprKind::Lit(_lit) => (), @@ -67,6 +98,49 @@ impl Context { }, } } else if r_ty.peel_refs().is_floating_point() && r_ty.peel_refs().is_floating_point() { +======= + let (_, r_ty) = (cx.typeck_results().expr_ty(l), cx.typeck_results().expr_ty(r)); + if r_ty.peel_refs().is_floating_point() && r_ty.peel_refs().is_floating_point() { +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= + let (_, r_ty) = (cx.typeck_results().expr_ty(l), cx.typeck_results().expr_ty(r)); + if r_ty.peel_refs().is_floating_point() && r_ty.peel_refs().is_floating_point() { +======= + let (l_ty, r_ty) = (cx.typeck_results().expr_ty(l), cx.typeck_results().expr_ty(r)); + if l_ty.peel_refs().is_integral() && r_ty.peel_refs().is_integral() { +<<<<<<< HEAD +<<<<<<< HEAD + if is_from_proc_macro(cx, expr) { +======= + if Self::skip_expr_involving_integers(cx, expr) { +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + if is_from_proc_macro(cx, expr) { +>>>>>>> d6390625d (Address comments) + return; + } + match op { + hir::BinOpKind::Div | hir::BinOpKind::Rem => match &r.kind { + hir::ExprKind::Lit(_lit) => (), + hir::ExprKind::Unary(hir::UnOp::Neg, expr) => { + if is_integer_literal(expr, 1) { + span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); + self.expr_id = Some(expr.hir_id); + } + }, + _ => { + span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); + self.expr_id = Some(expr.hir_id); + }, + }, + _ => { + span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); + self.expr_id = Some(expr.hir_id); + }, + } + } else if r_ty.peel_refs().is_floating_point() && r_ty.peel_refs().is_floating_point() { +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) span_lint(cx, FLOAT_ARITHMETIC, expr.span, "floating-point arithmetic detected"); self.expr_id = Some(expr.hir_id); } @@ -77,14 +151,70 @@ impl Context { return; } let ty = cx.typeck_results().expr_ty(arg); +<<<<<<< HEAD +<<<<<<< HEAD + if constant_simple(cx, cx.typeck_results(), expr).is_none() { + if ty.is_integral() { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if is_from_proc_macro(cx, expr) { +======= + if Self::skip_expr_involving_integers(cx, expr) { +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + if is_from_proc_macro(cx, expr) { +>>>>>>> d6390625d (Address comments) +======= + if is_from_proc_macro(cx, expr) { +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + if Self::skip_expr_involving_integers(cx, expr) { +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + if is_from_proc_macro(cx, expr) { +>>>>>>> d6390625d (Address comments) + return; + } + span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); + self.expr_id = Some(expr.hir_id); + } else if ty.is_floating_point() { + span_lint(cx, FLOAT_ARITHMETIC, expr.span, "floating-point arithmetic detected"); + self.expr_id = Some(expr.hir_id); + } +======= + if constant_simple(cx, cx.typeck_results(), expr).is_none() && ty.is_floating_point() { + span_lint(cx, FLOAT_ARITHMETIC, expr.span, "floating-point arithmetic detected"); + self.expr_id = Some(expr.hir_id); +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= + if constant_simple(cx, cx.typeck_results(), expr).is_none() && ty.is_floating_point() { + span_lint(cx, FLOAT_ARITHMETIC, expr.span, "floating-point arithmetic detected"); + self.expr_id = Some(expr.hir_id); +======= if constant_simple(cx, cx.typeck_results(), expr).is_none() { if ty.is_integral() { +<<<<<<< HEAD +<<<<<<< HEAD + if is_from_proc_macro(cx, expr) { +======= + if Self::skip_expr_involving_integers(cx, expr) { +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + if is_from_proc_macro(cx, expr) { +>>>>>>> d6390625d (Address comments) + return; + } span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); self.expr_id = Some(expr.hir_id); } else if ty.is_floating_point() { span_lint(cx, FLOAT_ARITHMETIC, expr.span, "floating-point arithmetic detected"); self.expr_id = Some(expr.hir_id); } +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) } } diff --git a/clippy_lints/src/operators/op_ref.rs b/clippy_lints/src/operators/op_ref.rs index d7917e86a861..932dd470f9eb 100644 --- a/clippy_lints/src/operators/op_ref.rs +++ b/clippy_lints/src/operators/op_ref.rs @@ -4,7 +4,9 @@ use clippy_utils::source::snippet; use clippy_utils::ty::{implements_trait, is_copy}; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{def::Res, def_id::DefId, BinOpKind, BorrowKind, Expr, ExprKind, GenericArg, ItemKind, QPath, TyKind}; +use rustc_hir::def::Res; +use rustc_hir::def_id::DefId; +use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, GenericArg, ItemKind, QPath, TyKind}; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index bbbcda069c55..40da002f4ff0 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -6,10 +6,9 @@ use clippy_utils::{ }; use if_chain::if_chain; use rustc_errors::Applicability; +use rustc_hir::def::Res; use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk}; -use rustc_hir::{ - def::Res, Arm, BindingAnnotation, Expr, ExprKind, MatchSource, Mutability, Pat, PatKind, Path, QPath, UnOp, -}; +use rustc_hir::{Arm, BindingAnnotation, Expr, ExprKind, MatchSource, Mutability, Pat, PatKind, Path, QPath, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::SyntaxContext; @@ -122,7 +121,7 @@ fn try_get_option_occurrence<'tcx>( ExprKind::Unary(UnOp::Deref, inner_expr) | ExprKind::AddrOf(_, _, inner_expr) => inner_expr, _ => expr, }; - let inner_pat = try_get_inner_pat(cx, pat)?; + let (inner_pat, is_result) = try_get_inner_pat_and_is_result(cx, pat)?; if_chain! { if let PatKind::Binding(bind_annotation, _, id, None) = inner_pat.kind; if let Some(some_captures) = can_move_expr_to_closure(cx, if_then); @@ -140,6 +139,9 @@ fn try_get_option_occurrence<'tcx>( let (as_ref, as_mut) = match &expr.kind { ExprKind::AddrOf(_, Mutability::Not, _) => (true, false), ExprKind::AddrOf(_, Mutability::Mut, _) => (false, true), + _ if let Some(mutb) = cx.typeck_results().expr_ty(expr).ref_mutability() => { + (mutb == Mutability::Not, mutb == Mutability::Mut) + } _ => (bind_annotation == BindingAnnotation::REF, bind_annotation == BindingAnnotation::REF_MUT), }; @@ -176,7 +178,7 @@ fn try_get_option_occurrence<'tcx>( ), none_expr: format!( "{}{}", - if method_sugg == "map_or" { "" } else { "|| " }, + if method_sugg == "map_or" { "" } else if is_result { "|_| " } else { "|| "}, Sugg::hir_with_context(cx, none_body, ctxt, "..", &mut app), ), }); @@ -186,11 +188,13 @@ fn try_get_option_occurrence<'tcx>( None } -fn try_get_inner_pat<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option<&'tcx Pat<'tcx>> { +fn try_get_inner_pat_and_is_result<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option<(&'tcx Pat<'tcx>, bool)> { if let PatKind::TupleStruct(ref qpath, [inner_pat], ..) = pat.kind { let res = cx.qpath_res(qpath, pat.hir_id); - if is_res_lang_ctor(cx, res, OptionSome) || is_res_lang_ctor(cx, res, ResultOk) { - return Some(inner_pat); + if is_res_lang_ctor(cx, res, OptionSome) { + return Some((inner_pat, false)); + } else if is_res_lang_ctor(cx, res, ResultOk) { + return Some((inner_pat, true)); } } None diff --git a/clippy_lints/src/panic_in_result_fn.rs b/clippy_lints/src/panic_in_result_fn.rs index 849cd03dd7bf..a049427d85d9 100644 --- a/clippy_lints/src/panic_in_result_fn.rs +++ b/clippy_lints/src/panic_in_result_fn.rs @@ -13,7 +13,7 @@ use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does - /// Checks for usage of `panic!`, `unimplemented!`, `todo!`, `unreachable!` or assertions in a function of type result. + /// Checks for usage of `panic!` or assertions in a function of type result. /// /// ### Why is this bad? /// For some codebases, it is desirable for functions of type result to return an error instead of crashing. Hence panicking macros should be avoided. @@ -37,7 +37,7 @@ declare_clippy_lint! { #[clippy::version = "1.48.0"] pub PANIC_IN_RESULT_FN, restriction, - "functions of type `Result<..>` that contain `panic!()`, `todo!()`, `unreachable()`, `unimplemented()` or assertion" + "functions of type `Result<..>` that contain `panic!()` or assertion" } declare_lint_pass!(PanicInResultFn => [PANIC_IN_RESULT_FN]); @@ -70,7 +70,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, body: &'tcx hir }; if matches!( cx.tcx.item_name(macro_call.def_id).as_str(), - "unimplemented" | "unreachable" | "panic" | "todo" | "assert" | "assert_eq" | "assert_ne" + "panic" | "assert" | "assert_eq" | "assert_ne" ) { panics.push(macro_call.span); ControlFlow::Continue(Descend::No) @@ -83,10 +83,10 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, body: &'tcx hir cx, PANIC_IN_RESULT_FN, impl_span, - "used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`", + "used `panic!()` or assertion in a function that returns `Result`", move |diag| { diag.help( - "`unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing", + "`panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing", ); diag.span_note(panics, "return Err() instead of panicking"); }, diff --git a/clippy_lints/src/partialeq_to_none.rs b/clippy_lints/src/partialeq_to_none.rs index 456ded3fc026..d9f5d1642d76 100644 --- a/clippy_lints/src/partialeq_to_none.rs +++ b/clippy_lints/src/partialeq_to_none.rs @@ -1,7 +1,6 @@ -use clippy_utils::{ - diagnostics::span_lint_and_sugg, is_res_lang_ctor, path_res, peel_hir_expr_refs, peel_ref_operators, sugg, - ty::is_type_diagnostic_item, -}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::{is_res_lang_ctor, path_res, peel_hir_expr_refs, peel_ref_operators, sugg}; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem}; use rustc_lint::{LateContext, LateLintPass}; diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs index 0d78c3048ba1..d20ea7245c12 100644 --- a/clippy_lints/src/pass_by_ref_or_value.rs +++ b/clippy_lints/src/pass_by_ref_or_value.rs @@ -1,5 +1,4 @@ -use std::cmp; -use std::iter; +use std::{cmp, iter}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; @@ -14,7 +13,7 @@ use rustc_hir as hir; use rustc_hir::intravisit::FnKind; use rustc_hir::{BindingAnnotation, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, Node, PatKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::adjustment::{Adjust, PointerCast}; +use rustc_middle::ty::adjustment::{Adjust, PointerCoercion}; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, RegionKind}; use rustc_session::{declare_tool_lint, impl_lint_pass}; @@ -195,7 +194,7 @@ impl<'tcx> PassByRefOrValue { .adjustments() .items() .flat_map(|(_, a)| a) - .any(|a| matches!(a.kind, Adjust::Pointer(PointerCast::UnsafeFnPointer))) + .any(|a| matches!(a.kind, Adjust::Pointer(PointerCoercion::UnsafeFnPointer))) { continue; } diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index fc550936165e..143a81c03f52 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -5,6 +5,7 @@ use clippy_utils::source::snippet_opt; use clippy_utils::ty::expr_sig; use clippy_utils::visitors::contains_unsafe_block; use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, path_def_id, path_to_local, paths}; +use hir::LifetimeName; use if_chain::if_chain; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::def_id::DefId; @@ -15,19 +16,19 @@ use rustc_hir::{ ImplItemKind, ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind, TyKind, Unsafety, }; +use rustc_hir_analysis::hir_ty_to_ty; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{self, Binder, Clause, ExistentialPredicate, List, PredicateKind, Ty}; +use rustc_middle::ty::{self, Binder, ClauseKind, ExistentialPredicate, List, PredicateKind, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; use rustc_span::sym; use rustc_span::symbol::Symbol; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; -use std::fmt; -use std::iter; +use std::{fmt, iter}; declare_clippy_lint! { /// ### What it does @@ -166,6 +167,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { cx, cx.tcx.fn_sig(item.owner_id).subst_identity().skip_binder().inputs(), sig.decl.inputs, + &sig.decl.output, &[], ) .filter(|arg| arg.mutability() == Mutability::Not) @@ -218,7 +220,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { check_mut_from_ref(cx, sig, Some(body)); let decl = sig.decl; let sig = cx.tcx.fn_sig(item_id).subst_identity().skip_binder(); - let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, body.params) + let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, &decl.output, body.params) .filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not) .collect(); let results = check_ptr_arg_usage(cx, body, &lint_args); @@ -386,11 +388,11 @@ impl<'tcx> DerefTy<'tcx> { fn ty(&self, cx: &LateContext<'tcx>) -> Ty<'tcx> { match *self { Self::Str => cx.tcx.types.str_, - Self::Path => cx.tcx.mk_adt( + Self::Path => Ty::new_adt(cx.tcx, cx.tcx.adt_def(cx.tcx.get_diagnostic_item(sym::Path).unwrap()), List::empty(), ), - Self::Slice(_, ty) => cx.tcx.mk_slice(ty), + Self::Slice(_, ty) => Ty::new_slice(cx.tcx,ty), } } @@ -407,29 +409,27 @@ impl<'tcx> DerefTy<'tcx> { } } +#[expect(clippy::too_many_lines)] fn check_fn_args<'cx, 'tcx: 'cx>( cx: &'cx LateContext<'tcx>, tys: &'tcx [Ty<'tcx>], hir_tys: &'tcx [hir::Ty<'tcx>], + ret_ty: &'tcx FnRetTy<'tcx>, params: &'tcx [Param<'tcx>], ) -> impl Iterator> + 'cx { tys.iter() .zip(hir_tys.iter()) .enumerate() - .filter_map(|(i, (ty, hir_ty))| { - if_chain! { - if let ty::Ref(_, ty, mutability) = *ty.kind(); - if let ty::Adt(adt, substs) = *ty.kind(); - - if let TyKind::Ref(lt, ref ty) = hir_ty.kind; - if let TyKind::Path(QPath::Resolved(None, path)) = ty.ty.kind; - + .filter_map(move |(i, (ty, hir_ty))| { + if let ty::Ref(_, ty, mutability) = *ty.kind() + && let ty::Adt(adt, substs) = *ty.kind() + && let TyKind::Ref(lt, ref ty) = hir_ty.kind + && let TyKind::Path(QPath::Resolved(None, path)) = ty.ty.kind // Check that the name as typed matches the actual name of the type. // e.g. `fn foo(_: &Foo)` shouldn't trigger the lint when `Foo` is an alias for `Vec` - if let [.., name] = path.segments; - if cx.tcx.item_name(adt.did()) == name.ident.name; - - then { + && let [.., name] = path.segments + && cx.tcx.item_name(adt.did()) == name.ident.name + { let emission_id = params.get(i).map_or(hir_ty.hir_id, |param| param.hir_id); let (method_renames, deref_ty) = match cx.tcx.get_diagnostic_name(adt.did()) { Some(sym::Vec) => ( @@ -454,30 +454,65 @@ fn check_fn_args<'cx, 'tcx: 'cx>( DerefTy::Path, ), Some(sym::Cow) if mutability == Mutability::Not => { - let ty_name = name.args + if let Some((lifetime, ty)) = name.args .and_then(|args| { - args.args.iter().find_map(|a| match a { - GenericArg::Type(x) => Some(x), - _ => None, - }) + if let [GenericArg::Lifetime(lifetime), ty] = args.args { + return Some((lifetime, ty)); + } + None }) - .and_then(|arg| snippet_opt(cx, arg.span)) - .unwrap_or_else(|| substs.type_at(1).to_string()); - span_lint_hir_and_then( - cx, - PTR_ARG, - emission_id, - hir_ty.span, - "using a reference to `Cow` is not recommended", - |diag| { - diag.span_suggestion( - hir_ty.span, - "change this to", - format!("&{}{ty_name}", mutability.prefix_str()), - Applicability::Unspecified, - ); + { + if !lifetime.is_anonymous() + && let FnRetTy::Return(ret_ty) = ret_ty + && let ret_ty = hir_ty_to_ty(cx.tcx, ret_ty) + && ret_ty + .walk() + .filter_map(|arg| { + arg.as_region().and_then(|lifetime| { + match lifetime.kind() { + ty::ReEarlyBound(r) => Some(r.def_id), + ty::ReLateBound(_, r) => r.kind.get_id(), + ty::ReFree(r) => r.bound_region.get_id(), + ty::ReStatic + | ty::ReVar(_) + | ty::RePlaceholder(_) + | ty::ReErased + | ty::ReError(_) => None, + } + }) + }) + .any(|def_id| { + matches!( + lifetime.res, + LifetimeName::Param(param_def_id) if def_id + .as_local() + .is_some_and(|def_id| def_id == param_def_id), + ) + }) + { + // `&Cow<'a, T>` when the return type uses 'a is okay + return None; } - ); + + let ty_name = + snippet_opt(cx, ty.span()).unwrap_or_else(|| substs.type_at(1).to_string()); + + span_lint_hir_and_then( + cx, + PTR_ARG, + emission_id, + hir_ty.span, + "using a reference to `Cow` is not recommended", + |diag| { + diag.span_suggestion( + hir_ty.span, + "change this to", + format!("&{}{ty_name}", mutability.prefix_str()), + Applicability::Unspecified, + ); + } + ); + } return None; }, _ => return None, @@ -495,7 +530,6 @@ fn check_fn_args<'cx, 'tcx: 'cx>( }, deref_ty, }); - } } None }) @@ -697,7 +731,7 @@ fn matches_preds<'tcx>( ObligationCause::dummy(), cx.param_env, cx.tcx - .mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Projection( + .mk_predicate(Binder::dummy(PredicateKind::Clause(ClauseKind::Projection( p.with_self_ty(cx.tcx, ty), )))), )), diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index 5269bbd1f1ac..e118f3363c66 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -1,20 +1,24 @@ +use crate::manual_let_else::{MatchLintBehaviour, MANUAL_LET_ELSE}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::higher; +use clippy_utils::msrvs::Msrv; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{ - eq_expr_value, get_parent_node, in_constant, is_else_clause, is_res_lang_ctor, path_to_local, path_to_local_id, - peel_blocks, peel_blocks_with_stmt, + eq_expr_value, get_parent_node, higher, in_constant, is_else_clause, is_path_lang_item, is_res_lang_ctor, + pat_and_expr_can_be_question_mark, path_to_local, path_to_local_id, peel_blocks, peel_blocks_with_stmt, }; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::def::Res; -use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk}; -use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, Node, PatKind, PathSegment, QPath}; +use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk}; +use rustc_hir::{ + BindingAnnotation, Block, ByRef, Expr, ExprKind, Local, Node, PatKind, PathSegment, QPath, Stmt, StmtKind, +}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; -use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::{sym, symbol::Symbol}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::sym; +use rustc_span::symbol::Symbol; declare_clippy_lint! { /// ### What it does @@ -41,7 +45,37 @@ declare_clippy_lint! { "checks for expressions that could be replaced by the question mark operator" } -declare_lint_pass!(QuestionMark => [QUESTION_MARK]); +pub struct QuestionMark { + pub(crate) msrv: Msrv, + pub(crate) matches_behaviour: MatchLintBehaviour, + /// Keeps track of how many try blocks we are in at any point during linting. + /// This allows us to answer the question "are we inside of a try block" + /// very quickly, without having to walk up the parent chain, by simply checking + /// if it is greater than zero. + /// As for why we need this in the first place: +<<<<<<< HEAD +<<<<<<< HEAD + try_block_depth_stack: Vec, +======= + try_block_depth: u32, +>>>>>>> 716305d4b ([`question_mark`]: don't lint inside of `try` block) +======= + try_block_depth_stack: Vec, +>>>>>>> 70610c001 (lint in nested bodies if `try` is in outer body) +} + +impl_lint_pass!(QuestionMark => [QUESTION_MARK, MANUAL_LET_ELSE]); + +impl QuestionMark { + #[must_use] + pub fn new(msrv: Msrv, matches_behaviour: MatchLintBehaviour) -> Self { + Self { + msrv, + matches_behaviour, + try_block_depth_stack: Vec::new(), + } + } +} enum IfBlockType<'hir> { /// An `if x.is_xxx() { a } else { b } ` expression. @@ -68,95 +102,26 @@ enum IfBlockType<'hir> { ), } -/// Checks if the given expression on the given context matches the following structure: -/// -/// ```ignore -/// if option.is_none() { -/// return None; -/// } -/// ``` -/// -/// ```ignore -/// if result.is_err() { -/// return result; -/// } -/// ``` -/// -/// If it matches, it will suggest to use the question mark operator instead -fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { - if_chain! { - if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr); - if !is_else_clause(cx.tcx, expr); - if let ExprKind::MethodCall(segment, caller, ..) = &cond.kind; - let caller_ty = cx.typeck_results().expr_ty(caller); - let if_block = IfBlockType::IfIs(caller, caller_ty, segment.ident.name, then, r#else); - if is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block); - then { - let mut applicability = Applicability::MachineApplicable; - let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability); - let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.param_env) && - !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..)); - let sugg = if let Some(else_inner) = r#else { - if eq_expr_value(cx, caller, peel_blocks(else_inner)) { - format!("Some({receiver_str}?)") - } else { - return; - } - } else { - format!("{receiver_str}{}?;", if by_ref { ".as_ref()" } else { "" }) - }; - - span_lint_and_sugg( - cx, - QUESTION_MARK, - expr.span, - "this block may be rewritten with the `?` operator", - "replace it with", - sugg, - applicability, - ); - } - } -} - -fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { - if_chain! { - if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else }) = higher::IfLet::hir(cx, expr); - if !is_else_clause(cx.tcx, expr); - if let PatKind::TupleStruct(ref path1, [field], ddpos) = let_pat.kind; - if ddpos.as_opt_usize().is_none(); - if let PatKind::Binding(BindingAnnotation(by_ref, _), bind_id, ident, None) = field.kind; - let caller_ty = cx.typeck_results().expr_ty(let_expr); - let if_block = IfBlockType::IfLet( - cx.qpath_res(path1, let_pat.hir_id), - caller_ty, - ident.name, - let_expr, - if_then, - if_else +fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) { + if let StmtKind::Local(Local { pat, init: Some(init_expr), els: Some(els), .. }) = stmt.kind && + let Block { stmts: &[], expr: Some(els), .. } = els && + let Some(inner_pat) = pat_and_expr_can_be_question_mark(cx, pat, els) + { + let mut applicability = Applicability::MaybeIncorrect; + let init_expr_str = snippet_with_applicability(cx, init_expr.span, "..", &mut applicability); + let receiver_str = snippet_with_applicability(cx, inner_pat.span, "..", &mut applicability); + let sugg = format!( + "let {receiver_str} = {init_expr_str}?;", + ); + span_lint_and_sugg( + cx, + QUESTION_MARK, + stmt.span, + "this `let...else` may be rewritten with the `?` operator", + "replace it with", + sugg, + applicability, ); - if (is_early_return(sym::Option, cx, &if_block) && path_to_local_id(peel_blocks(if_then), bind_id)) - || is_early_return(sym::Result, cx, &if_block); - if if_else.map(|e| eq_expr_value(cx, let_expr, peel_blocks(e))).filter(|e| *e).is_none(); - then { - let mut applicability = Applicability::MachineApplicable; - let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability); - let requires_semi = matches!(get_parent_node(cx.tcx, expr.hir_id), Some(Node::Stmt(_))); - let sugg = format!( - "{receiver_str}{}?{}", - if by_ref == ByRef::Yes { ".as_ref()" } else { "" }, - if requires_semi { ";" } else { "" } - ); - span_lint_and_sugg( - cx, - QUESTION_MARK, - expr.span, - "this block may be rewritten with the `?` operator", - "replace it with", - sugg, - applicability, - ); - } } } @@ -230,11 +195,193 @@ fn expr_return_none_or_err( } } +impl QuestionMark { + fn inside_try_block(&self) -> bool { +<<<<<<< HEAD +<<<<<<< HEAD + self.try_block_depth_stack.last() > Some(&0) +======= + self.try_block_depth > 0 +>>>>>>> 716305d4b ([`question_mark`]: don't lint inside of `try` block) +======= + self.try_block_depth_stack.last() > Some(&0) +>>>>>>> 70610c001 (lint in nested bodies if `try` is in outer body) + } + + /// Checks if the given expression on the given context matches the following structure: + /// + /// ```ignore + /// if option.is_none() { + /// return None; + /// } + /// ``` + /// + /// ```ignore + /// if result.is_err() { + /// return result; + /// } + /// ``` + /// + /// If it matches, it will suggest to use the question mark operator instead + fn check_is_none_or_err_and_early_return<'tcx>(&self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { + if_chain! { + if !self.inside_try_block(); + if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr); + if !is_else_clause(cx.tcx, expr); + if let ExprKind::MethodCall(segment, caller, ..) = &cond.kind; + let caller_ty = cx.typeck_results().expr_ty(caller); + let if_block = IfBlockType::IfIs(caller, caller_ty, segment.ident.name, then, r#else); + if is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block); + then { + let mut applicability = Applicability::MachineApplicable; + let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability); + let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.param_env) && + !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..)); + let sugg = if let Some(else_inner) = r#else { + if eq_expr_value(cx, caller, peel_blocks(else_inner)) { + format!("Some({receiver_str}?)") + } else { + return; + } + } else { + format!("{receiver_str}{}?;", if by_ref { ".as_ref()" } else { "" }) + }; + + span_lint_and_sugg( + cx, + QUESTION_MARK, + expr.span, + "this block may be rewritten with the `?` operator", + "replace it with", + sugg, + applicability, + ); + } + } + } + + fn check_if_let_some_or_err_and_early_return<'tcx>(&self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { + if_chain! { + if !self.inside_try_block(); + if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else }) = higher::IfLet::hir(cx, expr); + if !is_else_clause(cx.tcx, expr); + if let PatKind::TupleStruct(ref path1, [field], ddpos) = let_pat.kind; + if ddpos.as_opt_usize().is_none(); + if let PatKind::Binding(BindingAnnotation(by_ref, _), bind_id, ident, None) = field.kind; + let caller_ty = cx.typeck_results().expr_ty(let_expr); + let if_block = IfBlockType::IfLet( + cx.qpath_res(path1, let_pat.hir_id), + caller_ty, + ident.name, + let_expr, + if_then, + if_else + ); + if (is_early_return(sym::Option, cx, &if_block) && path_to_local_id(peel_blocks(if_then), bind_id)) + || is_early_return(sym::Result, cx, &if_block); + if if_else.map(|e| eq_expr_value(cx, let_expr, peel_blocks(e))).filter(|e| *e).is_none(); + then { + let mut applicability = Applicability::MachineApplicable; + let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability); + let requires_semi = matches!(get_parent_node(cx.tcx, expr.hir_id), Some(Node::Stmt(_))); + let sugg = format!( + "{receiver_str}{}?{}", + if by_ref == ByRef::Yes { ".as_ref()" } else { "" }, + if requires_semi { ";" } else { "" } + ); + span_lint_and_sugg( + cx, + QUESTION_MARK, + expr.span, + "this block may be rewritten with the `?` operator", + "replace it with", + sugg, + applicability, + ); + } + } + } +} + +fn is_try_block(cx: &LateContext<'_>, bl: &rustc_hir::Block<'_>) -> bool { + if let Some(expr) = bl.expr + && let rustc_hir::ExprKind::Call(callee, _) = expr.kind + { + is_path_lang_item(cx, callee, LangItem::TryTraitFromOutput) + } else { + false + } +} + impl<'tcx> LateLintPass<'tcx> for QuestionMark { + fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { + if !in_constant(cx, stmt.hir_id) { + check_let_some_else_return_none(cx, stmt); + } + self.check_manual_let_else(cx, stmt); + } fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if !in_constant(cx, expr.hir_id) { - check_is_none_or_err_and_early_return(cx, expr); - check_if_let_some_or_err_and_early_return(cx, expr); + self.check_is_none_or_err_and_early_return(cx, expr); + self.check_if_let_some_or_err_and_early_return(cx, expr); + } + } + + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx rustc_hir::Block<'tcx>) { + if is_try_block(cx, block) { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 70610c001 (lint in nested bodies if `try` is in outer body) + *self + .try_block_depth_stack + .last_mut() + .expect("blocks are always part of bodies and must have a depth") += 1; +<<<<<<< HEAD + } + } + + fn check_body(&mut self, _: &LateContext<'tcx>, _: &'tcx rustc_hir::Body<'tcx>) { + self.try_block_depth_stack.push(0); + } + + fn check_body_post(&mut self, _: &LateContext<'tcx>, _: &'tcx rustc_hir::Body<'tcx>) { + self.try_block_depth_stack.pop(); + } + + fn check_block_post(&mut self, cx: &LateContext<'tcx>, block: &'tcx rustc_hir::Block<'tcx>) { + if is_try_block(cx, block) { + *self + .try_block_depth_stack + .last_mut() + .expect("blocks are always part of bodies and must have a depth") -= 1; +======= + self.try_block_depth += 1; +======= +>>>>>>> 70610c001 (lint in nested bodies if `try` is in outer body) + } + } + + fn check_body(&mut self, _: &LateContext<'tcx>, _: &'tcx rustc_hir::Body<'tcx>) { + self.try_block_depth_stack.push(0); + } + + fn check_body_post(&mut self, _: &LateContext<'tcx>, _: &'tcx rustc_hir::Body<'tcx>) { + self.try_block_depth_stack.pop(); + } + + fn check_block_post(&mut self, cx: &LateContext<'tcx>, block: &'tcx rustc_hir::Block<'tcx>) { + if is_try_block(cx, block) { +<<<<<<< HEAD + self.try_block_depth -= 1; +>>>>>>> 716305d4b ([`question_mark`]: don't lint inside of `try` block) +======= + *self + .try_block_depth_stack + .last_mut() + .expect("blocks are always part of bodies and must have a depth") -= 1; +>>>>>>> 70610c001 (lint in nested bodies if `try` is in outer body) } } + extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/question_mark_used.rs b/clippy_lints/src/question_mark_used.rs index 9b678e8d753c..ff66b8a00953 100644 --- a/clippy_lints/src/question_mark_used.rs +++ b/clippy_lints/src/question_mark_used.rs @@ -24,7 +24,7 @@ declare_clippy_lint! { /// ```ignore /// utility_macro!(expr); /// ``` - #[clippy::version = "pre 1.29.0"] + #[clippy::version = "1.69.0"] pub QUESTION_MARK_USED, restriction, "complains if the question mark operator is used" diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index fc655fe2d0bb..3287675a82de 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -1,10 +1,9 @@ use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::higher; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability}; use clippy_utils::sugg::Sugg; -use clippy_utils::{get_parent_expr, in_constant, is_integer_const, path_to_local}; +use clippy_utils::{get_parent_expr, higher, in_constant, is_integer_const, path_to_local}; use if_chain::if_chain; use rustc_ast::ast::RangeLimits; use rustc_errors::Applicability; @@ -296,8 +295,8 @@ fn check_possible_range_contains( } } -struct RangeBounds<'a> { - val: Constant, +struct RangeBounds<'a, 'tcx> { + val: Constant<'tcx>, expr: &'a Expr<'a>, id: HirId, name_span: Span, @@ -309,7 +308,7 @@ struct RangeBounds<'a> { // Takes a binary expression such as x <= 2 as input // Breaks apart into various pieces, such as the value of the number, // hir id of the variable, and direction/inclusiveness of the operator -fn check_range_bounds<'a>(cx: &'a LateContext<'_>, ex: &'a Expr<'_>) -> Option> { +fn check_range_bounds<'a, 'tcx>(cx: &'a LateContext<'tcx>, ex: &'a Expr<'_>) -> Option> { if let ExprKind::Binary(ref op, l, r) = ex.kind { let (inclusive, ordering) = match op.node { BinOpKind::Gt => (false, Ordering::Greater), @@ -319,7 +318,7 @@ fn check_range_bounds<'a>(cx: &'a LateContext<'_>, ex: &'a Expr<'_>) -> Option return None, }; if let Some(id) = path_to_local(l) { - if let Some((c, _)) = constant(cx, cx.typeck_results(), r) { + if let Some(c) = constant(cx, cx.typeck_results(), r) { return Some(RangeBounds { val: c, expr: r, @@ -331,7 +330,7 @@ fn check_range_bounds<'a>(cx: &'a LateContext<'_>, ex: &'a Expr<'_>) -> Option, expr: &Expr<'_>) { if let Some(higher::Range { start: Some(start), end: Some(end), limits }) = higher::Range::hir(expr); let ty = cx.typeck_results().expr_ty(start); if let ty::Int(_) | ty::Uint(_) = ty.kind(); - if let Some((start_idx, _)) = constant(cx, cx.typeck_results(), start); - if let Some((end_idx, _)) = constant(cx, cx.typeck_results(), end); + if let Some(start_idx) = constant(cx, cx.typeck_results(), start); + if let Some(end_idx) = constant(cx, cx.typeck_results(), end); if let Some(ordering) = Constant::partial_cmp(cx.tcx, ty, &start_idx, &end_idx); if is_empty_range(limits, ordering); then { diff --git a/clippy_lints/src/raw_strings.rs b/clippy_lints/src/raw_strings.rs new file mode 100644 index 000000000000..0b6be59ff215 --- /dev/null +++ b/clippy_lints/src/raw_strings.rs @@ -0,0 +1,281 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +use std::{iter::once, ops::ControlFlow}; + +======= +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= +use std::{iter::once, ops::ControlFlow}; + +>>>>>>> 8cb6c8699 (change category and refactor) +use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet}; +use rustc_ast::{ + ast::{Expr, ExprKind}, + token::LitKind, +}; +======= +use std::iter::once; +use std::ops::ControlFlow; + +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet; +use rustc_ast::ast::{Expr, ExprKind}; +use rustc_ast::token::LitKind; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_errors::Applicability; +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_tool_lint, impl_lint_pass}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for raw string literals where a string literal can be used instead. + /// + /// ### Why is this bad? +<<<<<<< HEAD +<<<<<<< HEAD + /// It's just unnecessary, but there are many cases where using a raw string literal is more + /// idiomatic than a string literal, so it's opt-in. +======= + /// It's just unnecessary. +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= + /// It's just unnecessary, but there are many cases where using a raw string literal is more + /// idiomatic than a string literal, so it's opt-in. +>>>>>>> 8cb6c8699 (change category and refactor) + /// + /// ### Example + /// ```rust + /// let r = r"Hello, world!"; + /// ``` + /// Use instead: + /// ```rust + /// let r = "Hello, world!"; + /// ``` + #[clippy::version = "1.72.0"] +<<<<<<< HEAD +<<<<<<< HEAD + pub NEEDLESS_RAW_STRINGS, + restriction, +======= + pub NEEDLESS_RAW_STRING, + complexity, +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= + pub NEEDLESS_RAW_STRINGS, + restriction, +>>>>>>> 8cb6c8699 (change category and refactor) + "suggests using a string literal when a raw string literal is unnecessary" +} +declare_clippy_lint! { + /// ### What it does + /// Checks for raw string literals with an unnecessary amount of hashes around them. + /// + /// ### Why is this bad? + /// It's just unnecessary, and makes it look like there's more escaping needed than is actually + /// necessary. + /// + /// ### Example + /// ```rust + /// let r = r###"Hello, "world"!"###; + /// ``` + /// Use instead: + /// ```rust + /// let r = r#"Hello, "world"!"#; + /// ``` + #[clippy::version = "1.72.0"] + pub NEEDLESS_RAW_STRING_HASHES, +<<<<<<< HEAD +<<<<<<< HEAD + style, + "suggests reducing the number of hashes around a raw string literal" +} +impl_lint_pass!(RawStrings => [NEEDLESS_RAW_STRINGS, NEEDLESS_RAW_STRING_HASHES]); +======= + complexity, + "suggests reducing the number of hashes around a raw string literal" +} +impl_lint_pass!(RawStrings => [NEEDLESS_RAW_STRING, NEEDLESS_RAW_STRING_HASHES]); +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= + style, + "suggests reducing the number of hashes around a raw string literal" +} +impl_lint_pass!(RawStrings => [NEEDLESS_RAW_STRINGS, NEEDLESS_RAW_STRING_HASHES]); +>>>>>>> 8cb6c8699 (change category and refactor) + +pub struct RawStrings { + pub needless_raw_string_hashes_allow_one: bool, +} + +impl EarlyLintPass for RawStrings { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { + if !in_external_macro(cx.sess(), expr.span) + && let ExprKind::Lit(lit) = expr.kind +<<<<<<< HEAD +<<<<<<< HEAD + && let LitKind::StrRaw(max) | LitKind::ByteStrRaw(max) | LitKind::CStrRaw(max) = lit.kind + { + let str = lit.symbol.as_str(); +======= + && let LitKind::StrRaw(num) | LitKind::ByteStrRaw(num) | LitKind::CStrRaw(num) = lit.kind + { +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= + && let LitKind::StrRaw(max) | LitKind::ByteStrRaw(max) | LitKind::CStrRaw(max) = lit.kind + { + let str = lit.symbol.as_str(); +>>>>>>> 8cb6c8699 (change category and refactor) + let prefix = match lit.kind { + LitKind::StrRaw(..) => "r", + LitKind::ByteStrRaw(..) => "br", + LitKind::CStrRaw(..) => "cr", + _ => unreachable!(), + }; + if !snippet(cx, expr.span, prefix).trim().starts_with(prefix) { + return; + } + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if !str.contains(['\\', '"']) { + span_lint_and_sugg( + cx, + NEEDLESS_RAW_STRINGS, +======= + if !lit.symbol.as_str().contains(['\\', '"']) { + span_lint_and_sugg( + cx, + NEEDLESS_RAW_STRING, +>>>>>>> cb52d19ce (don't lint `needless_raw_string_hashes` when it's unnecessary) +======= + if !str.contains(['\\', '"']) { + span_lint_and_sugg( + cx, + NEEDLESS_RAW_STRINGS, +>>>>>>> 8cb6c8699 (change category and refactor) + expr.span, + "unnecessary raw string literal", + "try", + format!("{}\"{}\"", prefix.replace('r', ""), lit.symbol), + Applicability::MachineApplicable, + ); + + return; + } + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 8cb6c8699 (change category and refactor) + let req = { + let mut following_quote = false; + let mut req = 0; + // `once` so a raw string ending in hashes is still checked + let num = str.as_bytes().iter().chain(once(&0)).try_fold(0u8, |acc, &b| { + match b { + b'"' if !following_quote => (following_quote, req) = (true, 1), + // I'm a bit surprised the compiler didn't optimize this out, there's no + // branch but it still ends up doing an unnecessary comparison, it's: + // - cmp r9b,1h + // - sbb cl,-1h + // which will add 1 if it's true. With this change, it becomes: + // - add cl,r9b + // isn't that so much nicer? + b'#' => req += u8::from(following_quote), + _ => { + if following_quote { + following_quote = false; +<<<<<<< HEAD + + if req == max { + return ControlFlow::Break(req); + } + + return ControlFlow::Continue(acc.max(req)); + } + }, + } + + ControlFlow::Continue(acc) + }); + + match num { + ControlFlow::Continue(num) | ControlFlow::Break(num) => num, + } + }; + + if req < max { +======= + #[allow(clippy::cast_possible_truncation)] +======= +======= +>>>>>>> cb52d19ce (don't lint `needless_raw_string_hashes` when it's unnecessary) + #[expect(clippy::cast_possible_truncation)] +>>>>>>> ec765d951 (Update raw_strings.rs) + let req = lit.symbol.as_str().as_bytes() + .split(|&b| b == b'"') + .skip(1) + .map(|bs| 1 + bs.iter().take_while(|&&b| b == b'#').count() as u8) + .max() + .unwrap_or(0); + + if req < num { +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= + + if req == max { + return ControlFlow::Break(req); + } + + return ControlFlow::Continue(acc.max(req)); + } + }, + } + + ControlFlow::Continue(acc) + }); + + match num { + ControlFlow::Continue(num) | ControlFlow::Break(num) => num, + } + }; + + if req < max { +>>>>>>> 8cb6c8699 (change category and refactor) + let hashes = "#".repeat(req as usize); + + span_lint_and_sugg( + cx, + NEEDLESS_RAW_STRING_HASHES, + expr.span, + "unnecessary hashes around raw string literal", + "try", + format!(r#"{prefix}{hashes}"{}"{hashes}"#, lit.symbol), + Applicability::MachineApplicable, + ); + } +<<<<<<< HEAD +<<<<<<< HEAD +======= + + if !lit.symbol.as_str().contains(['\\', '"']) { + span_lint_and_sugg( + cx, + NEEDLESS_RAW_STRING, + expr.span, + "unnecessary raw string literal", + "try", + format!("{}\"{}\"", prefix.replace('r', ""), lit.symbol), + Applicability::MachineApplicable, + ); + } +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= +>>>>>>> cb52d19ce (don't lint `needless_raw_string_hashes` when it's unnecessary) + } + } +} diff --git a/clippy_lints/src/rc_clone_in_vec_init.rs b/clippy_lints/src/rc_clone_in_vec_init.rs index e82aa3a7b989..a2e7ae6d79ab 100644 --- a/clippy_lints/src/rc_clone_in_vec_init.rs +++ b/clippy_lints/src/rc_clone_in_vec_init.rs @@ -1,10 +1,9 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::VecArgs; -use clippy_utils::last_path_segment; use clippy_utils::macros::root_macro_call_first_node; -use clippy_utils::paths; use clippy_utils::source::{indent_of, snippet}; use clippy_utils::ty::match_type; +use clippy_utils::{last_path_segment, paths}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, QPath, TyKind}; use rustc_lint::{LateContext, LateLintPass}; diff --git a/clippy_lints/src/read_zero_byte_vec.rs b/clippy_lints/src/read_zero_byte_vec.rs index fa107858863a..2bf90815caad 100644 --- a/clippy_lints/src/read_zero_byte_vec.rs +++ b/clippy_lints/src/read_zero_byte_vec.rs @@ -1,9 +1,7 @@ -use clippy_utils::{ - diagnostics::{span_lint, span_lint_and_sugg}, - higher::{get_vec_init_kind, VecInitKind}, - source::snippet, - visitors::for_each_expr, -}; +use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; +use clippy_utils::higher::{get_vec_init_kind, VecInitKind}; +use clippy_utils::source::snippet; +use clippy_utils::visitors::for_each_expr; use core::ops::ControlFlow; use hir::{Expr, ExprKind, Local, PatKind, PathSegment, QPath, StmtKind}; use rustc_errors::Applicability; diff --git a/clippy_lints/src/redundant_async_block.rs b/clippy_lints/src/redundant_async_block.rs index a0f831764d07..534b2762ba76 100644 --- a/clippy_lints/src/redundant_async_block.rs +++ b/clippy_lints/src/redundant_async_block.rs @@ -1,15 +1,14 @@ use std::ops::ControlFlow; -use clippy_utils::{ - diagnostics::span_lint_and_sugg, - peel_blocks, - source::{snippet, walk_span_to_context}, - visitors::for_each_expr, -}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::peel_blocks; +use clippy_utils::source::{snippet, walk_span_to_context}; +use clippy_utils::visitors::for_each_expr; use rustc_errors::Applicability; use rustc_hir::{AsyncGeneratorKind, Closure, Expr, ExprKind, GeneratorKind, MatchSource}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::{lint::in_external_macro, ty::UpvarCapture}; +use rustc_middle::lint::in_external_macro; +use rustc_middle::ty::UpvarCapture; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { @@ -35,7 +34,7 @@ declare_clippy_lint! { /// }; /// let fut = f; /// ``` - #[clippy::version = "1.69.0"] + #[clippy::version = "1.70.0"] pub REDUNDANT_ASYNC_BLOCK, complexity, "`async { future.await }` can be replaced by `future`" diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index 944a33cc3e53..e36adef555e6 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -57,7 +57,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.32.0"] pub REDUNDANT_CLONE, - perf, + nursery, "`clone()` of an owned value that is going to be dropped immediately" } @@ -320,8 +320,6 @@ fn base_local_and_movability<'tcx>( mir: &mir::Body<'tcx>, place: mir::Place<'tcx>, ) -> (mir::Local, CannotMoveOut) { - use rustc_middle::mir::PlaceRef; - // Dereference. You cannot move things out from a borrowed value. let mut deref = false; // Accessing a field of an ADT that has `Drop`. Moving the field out will cause E0509. @@ -330,17 +328,14 @@ fn base_local_and_movability<'tcx>( // underlying type implements Copy let mut slice = false; - let PlaceRef { local, mut projection } = place.as_ref(); - while let [base @ .., elem] = projection { - projection = base; + for (base, elem) in place.as_ref().iter_projections() { + let base_ty = base.ty(&mir.local_decls, cx.tcx).ty; deref |= matches!(elem, mir::ProjectionElem::Deref); - field |= matches!(elem, mir::ProjectionElem::Field(..)) - && has_drop(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty); - slice |= matches!(elem, mir::ProjectionElem::Index(..)) - && !is_copy(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty); + field |= matches!(elem, mir::ProjectionElem::Field(..)) && has_drop(cx, base_ty); + slice |= matches!(elem, mir::ProjectionElem::Index(..)) && !is_copy(cx, base_ty); } - (local, deref || field || slice) + (place.local, deref || field || slice) } #[derive(Default)] diff --git a/clippy_lints/src/redundant_closure_call.rs b/clippy_lints/src/redundant_closure_call.rs index 2a42e73488f1..ae3e2217f976 100644 --- a/clippy_lints/src/redundant_closure_call.rs +++ b/clippy_lints/src/redundant_closure_call.rs @@ -1,14 +1,13 @@ +use crate::rustc_lint::LintContext; use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; +use clippy_utils::get_parent_expr; use clippy_utils::sugg::Sugg; use if_chain::if_chain; -use rustc_ast::ast; -use rustc_ast::visit as ast_visit; -use rustc_ast::visit::Visitor as AstVisitor; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::intravisit as hir_visit; -use rustc_hir::intravisit::Visitor as HirVisitor; -use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; +use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor}; +use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -51,59 +50,174 @@ impl ReturnVisitor { } } -impl<'ast> ast_visit::Visitor<'ast> for ReturnVisitor { - fn visit_expr(&mut self, ex: &'ast ast::Expr) { - if let ast::ExprKind::Ret(_) | ast::ExprKind::Try(_) = ex.kind { +impl<'tcx> Visitor<'tcx> for ReturnVisitor { + fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { + if let hir::ExprKind::Ret(_) | hir::ExprKind::Match(.., hir::MatchSource::TryDesugar) = ex.kind { self.found_return = true; + } else { + hir_visit::walk_expr(self, ex); } +<<<<<<< HEAD +<<<<<<< HEAD +======= - ast_visit::walk_expr(self, ex); + hir_visit::walk_expr(self, ex); +>>>>>>> 7280ad9f7 ([`redundant_closure_call`]: handle nested closures) +======= +>>>>>>> 3fe2478ec (don't unnecessarily walk more in visitor and add more tests) } } -impl EarlyLintPass for RedundantClosureCall { - fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) { +/// Checks if the body is owned by an async closure +fn is_async_closure(body: &hir::Body<'_>) -> bool { + if let hir::ExprKind::Closure(closure) = body.value.kind + && let [resume_ty] = closure.fn_decl.inputs + && let hir::TyKind::Path(hir::QPath::LangItem(hir::LangItem::ResumeTy, ..)) = resume_ty.kind + { + true + } else { + false + } +} + +/// Tries to find the innermost closure: +<<<<<<< HEAD +<<<<<<< HEAD +/// ```rust,ignore +======= +/// ```rust +>>>>>>> 7280ad9f7 ([`redundant_closure_call`]: handle nested closures) +======= +/// ```rust,ignore +>>>>>>> e305b0730 (fix docs) +/// (|| || || || 42)()()()() +/// ^^^^^^^^^^^^^^ given this nested closure expression +/// ^^^^^ we want to return this closure +/// ``` +/// It also has a parameter for how many steps to go in at most, so as to +/// not take more closures than there are calls. +fn find_innermost_closure<'tcx>( + cx: &LateContext<'tcx>, + mut expr: &'tcx hir::Expr<'tcx>, + mut steps: usize, +) -> Option<(&'tcx hir::Expr<'tcx>, &'tcx hir::FnDecl<'tcx>, hir::IsAsync)> { + let mut data = None; + + while let hir::ExprKind::Closure(closure) = expr.kind + && let body = cx.tcx.hir().body(closure.body) + && { + let mut visitor = ReturnVisitor::new(); + visitor.visit_expr(body.value); + !visitor.found_return + } + && steps > 0 + { + expr = body.value; + data = Some((body.value, closure.fn_decl, if is_async_closure(body) { + hir::IsAsync::Async + } else { + hir::IsAsync::NotAsync + })); + steps -= 1; + } + + data +} + +/// "Walks up" the chain of calls to find the outermost call expression, and returns the depth: +<<<<<<< HEAD +<<<<<<< HEAD +/// ```rust,ignore +/// (|| || || 3)()()() +/// ^^ this is the call expression we were given +/// ^^ this is what we want to return (and the depth is 3) +======= +/// ```rust +/// (|| || || 3)()()() +/// ^^ this is the call expression we were given +/// ^^ this is what we want to return (and the depth is 3) +>>>>>>> 7280ad9f7 ([`redundant_closure_call`]: handle nested closures) +======= +/// ```rust,ignore +/// (|| || || 3)()()() +/// ^^ this is the call expression we were given +/// ^^ this is what we want to return (and the depth is 3) +>>>>>>> e305b0730 (fix docs) +/// ``` +fn get_parent_call_exprs<'tcx>( + cx: &LateContext<'tcx>, + mut expr: &'tcx hir::Expr<'tcx>, +) -> (&'tcx hir::Expr<'tcx>, usize) { + let mut depth = 1; + while let Some(parent) = get_parent_expr(cx, expr) + && let hir::ExprKind::Call(recv, _) = parent.kind +<<<<<<< HEAD +<<<<<<< HEAD + && expr.span == recv.span +======= + && let hir::ExprKind::Call(..) = recv.kind +>>>>>>> 7280ad9f7 ([`redundant_closure_call`]: handle nested closures) +======= + && expr.span == recv.span +>>>>>>> 3fe2478ec (don't unnecessarily walk more in visitor and add more tests) + { + expr = parent; + depth += 1; + } + (expr, depth) +} + +impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { if in_external_macro(cx.sess(), expr.span) { return; } - if_chain! { - if let ast::ExprKind::Call(ref paren, _) = expr.kind; - if let ast::ExprKind::Paren(ref closure) = paren.kind; - if let ast::ExprKind::Closure(box ast::Closure { ref asyncness, ref fn_decl, ref body, .. }) = closure.kind; - then { - let mut visitor = ReturnVisitor::new(); - visitor.visit_expr(body); - if !visitor.found_return { - span_lint_and_then( - cx, - REDUNDANT_CLOSURE_CALL, - expr.span, - "try not to call a closure in the expression where it is declared", - |diag| { - if fn_decl.inputs.is_empty() { - let mut app = Applicability::MachineApplicable; - let mut hint = Sugg::ast(cx, body, "..", closure.span.ctxt(), &mut app); - - if asyncness.is_async() { - // `async x` is a syntax error, so it becomes `async { x }` - if !matches!(body.kind, ast::ExprKind::Block(_, _)) { - hint = hint.blockify(); - } - - hint = hint.asyncify(); - } - - diag.span_suggestion(expr.span, "try doing something like", hint.to_string(), app); + + if let hir::ExprKind::Call(recv, _) = expr.kind + // don't lint if the receiver is a call, too. + // we do this in order to prevent linting multiple times; consider: + // `(|| || 1)()()` + // ^^ we only want to lint for this call (but we walk up the calls to consider both calls). + // without this check, we'd end up linting twice. + && !matches!(recv.kind, hir::ExprKind::Call(..)) + && let (full_expr, call_depth) = get_parent_call_exprs(cx, expr) + && let Some((body, fn_decl, generator_kind)) = find_innermost_closure(cx, recv, call_depth) + { + span_lint_and_then( + cx, + REDUNDANT_CLOSURE_CALL, + full_expr.span, + "try not to call a closure in the expression where it is declared", + |diag| { + if fn_decl.inputs.is_empty() { + let mut applicability = Applicability::MachineApplicable; + let mut hint = Sugg::hir_with_context(cx, body, full_expr.span.ctxt(), "..", &mut applicability); + + if generator_kind.is_async() + && let hir::ExprKind::Closure(closure) = body.kind + { + let async_closure_body = cx.tcx.hir().body(closure.body); + + // `async x` is a syntax error, so it becomes `async { x }` + if !matches!(async_closure_body.value.kind, hir::ExprKind::Block(_, _)) { + hint = hint.blockify(); } - }, - ); + + hint = hint.asyncify(); + } + + diag.span_suggestion( + full_expr.span, + "try doing something like", + hint.maybe_par(), + applicability + ); + } } - } + ); } } -} -impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) { fn count_closure_usage<'tcx>( cx: &LateContext<'tcx>, diff --git a/clippy_lints/src/redundant_slicing.rs b/clippy_lints/src/redundant_slicing.rs index 2fdd775ad489..c70ce83a9c45 100644 --- a/clippy_lints/src/redundant_slicing.rs +++ b/clippy_lints/src/redundant_slicing.rs @@ -7,6 +7,7 @@ use rustc_ast::util::parser::PREC_PREFIX; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability}; use rustc_lint::{LateContext, LateLintPass, Lint}; +use rustc_middle::ty::Ty; use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::subst::GenericArg; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -134,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { } else if let Some(target_id) = cx.tcx.lang_items().deref_target() { if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions( cx.param_env, - cx.tcx.mk_projection(target_id, cx.tcx.mk_substs(&[GenericArg::from(indexed_ty)])), + Ty::new_projection(cx.tcx,target_id, cx.tcx.mk_substs(&[GenericArg::from(indexed_ty)])), ) { if deref_ty == expr_ty { let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0; diff --git a/clippy_lints/src/redundant_type_annotations.rs b/clippy_lints/src/redundant_type_annotations.rs new file mode 100644 index 000000000000..6120267b8517 --- /dev/null +++ b/clippy_lints/src/redundant_type_annotations.rs @@ -0,0 +1,301 @@ +use clippy_utils::diagnostics::span_lint; +use rustc_ast::LitKind; +use rustc_hir as hir; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::Ty; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// Warns about needless / redundant type annotations. + /// + /// ### Why is this bad? + /// Code without type annotations is shorter and in most cases + /// more idiomatic and easier to modify. + /// +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a9b468f2b (Add `Limitations` section) + /// ### Limitations + /// This lint doesn't support: + /// + /// - Generics + /// - Refs returned from anything else than a `MethodCall` + /// - Complex types (tuples, arrays, etc...) + /// - `Path` to anything else than a primitive type. + /// +<<<<<<< HEAD +======= +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= +>>>>>>> a9b468f2b (Add `Limitations` section) + /// ### Example + /// ```rust + /// let foo: String = String::new(); + /// ``` + /// Use instead: + /// ```rust + /// let foo = String::new(); + /// ``` + #[clippy::version = "1.70.0"] + pub REDUNDANT_TYPE_ANNOTATIONS, +<<<<<<< HEAD +<<<<<<< HEAD + restriction, +======= + pedantic, +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + restriction, +>>>>>>> 6776608f2 (Move `redundant_type_annotations` to restriction) + "warns about needless / redundant type annotations." +} +declare_lint_pass!(RedundantTypeAnnotations => [REDUNDANT_TYPE_ANNOTATIONS]); + +fn is_same_type<'tcx>(cx: &LateContext<'tcx>, ty_resolved_path: hir::def::Res, func_return_type: Ty<'tcx>) -> bool { + // type annotation is primitive + if let hir::def::Res::PrimTy(primty) = ty_resolved_path + && func_return_type.is_primitive() + && let Some(func_return_type_sym) = func_return_type.primitive_symbol() + { + return primty.name() == func_return_type_sym; + } + + // type annotation is any other non generic type + if let hir::def::Res::Def(_, defid) = ty_resolved_path + && let Some(annotation_ty) = cx.tcx.type_of(defid).no_bound_vars() + { + return annotation_ty == func_return_type; + } + + false +} + +fn func_hir_id_to_func_ty<'tcx>(cx: &LateContext<'tcx>, hir_id: hir::hir_id::HirId) -> Option> { + if let Some((defkind, func_defid)) = cx.typeck_results().type_dependent_def(hir_id) + && defkind == hir::def::DefKind::AssocFn + && let Some(init_ty) = cx.tcx.type_of(func_defid).no_bound_vars() + { + Some(init_ty) + } else { + None + } +} + +fn func_ty_to_return_type<'tcx>(cx: &LateContext<'tcx>, func_ty: Ty<'tcx>) -> Option> { +<<<<<<< HEAD +<<<<<<< HEAD + if func_ty.is_fn() { + Some(func_ty.fn_sig(cx.tcx).output().skip_binder()) +======= + if func_ty.is_fn() + && let Some(return_type) = func_ty.fn_sig(cx.tcx).output().no_bound_vars() + { + Some(return_type) +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + if func_ty.is_fn() { + Some(func_ty.fn_sig(cx.tcx).output().skip_binder()) +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + } else { + None + } +} + +/// Extracts the fn Ty, e.g. `fn() -> std::string::String {f}` +fn extract_fn_ty<'tcx>( + cx: &LateContext<'tcx>, + call: &hir::Expr<'tcx>, + func_return_path: &hir::QPath<'tcx>, +) -> Option> { + match func_return_path { + // let a: String = f(); where f: fn f() -> String + hir::QPath::Resolved(_, resolved_path) => { + if let hir::def::Res::Def(_, defid) = resolved_path.res + && let Some(middle_ty_init) = cx.tcx.type_of(defid).no_bound_vars() + { + Some(middle_ty_init) + } else { + None + } + }, + // Associated functions like + // let a: String = String::new(); + // let a: String = String::get_string(); + hir::QPath::TypeRelative(..) => func_hir_id_to_func_ty(cx, call.hir_id), + hir::QPath::LangItem(..) => None, + } +} + +fn is_redundant_in_func_call<'tcx>( + cx: &LateContext<'tcx>, + ty_resolved_path: hir::def::Res, + call: &hir::Expr<'tcx>, +) -> bool { + if let hir::ExprKind::Path(init_path) = &call.kind { + let func_type = extract_fn_ty(cx, call, init_path); + + if let Some(func_type) = func_type + && let Some(init_return_type) = func_ty_to_return_type(cx, func_type) + { + return is_same_type(cx, ty_resolved_path, init_return_type); + } + } + + false +} + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +fn extract_primty(ty_kind: &hir::TyKind<'_>) -> Option { +======= +fn extract_primty<'tcx>(ty_kind: &hir::TyKind<'tcx>) -> Option { +>>>>>>> 6f26df1c9 (Extract common logic to function) +======= +fn extract_primty(ty_kind: &hir::TyKind<'_>) -> Option { +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + if let hir::TyKind::Path(ty_path) = ty_kind + && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path + && let hir::def::Res::PrimTy(primty) = resolved_path_ty.res + { + Some(primty) + } else { + None + } +} + +<<<<<<< HEAD +======= +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= +>>>>>>> 6f26df1c9 (Extract common logic to function) +impl LateLintPass<'_> for RedundantTypeAnnotations { + fn check_local<'tcx>(&mut self, cx: &LateContext<'tcx>, local: &'tcx rustc_hir::Local<'tcx>) { + // type annotation part + if !local.span.from_expansion() + && let Some(ty) = &local.ty + + // initialization part + && let Some(init) = local.init + { + match &init.kind { + // When the initialization is a call to a function + hir::ExprKind::Call(init_call, _) => { + if let hir::TyKind::Path(ty_path) = &ty.kind + && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path + + && is_redundant_in_func_call(cx, resolved_path_ty.res, init_call) { + span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation"); + } + }, + hir::ExprKind::MethodCall(_, _, _, _) => { +<<<<<<< HEAD +<<<<<<< HEAD + let mut is_ref = false; + let mut ty_kind = &ty.kind; + + // If the annotation is a ref we "peel" it + if let hir::TyKind::Ref(_, mut_ty) = &ty.kind { + is_ref = true; + ty_kind = &mut_ty.ty.kind; + } + + if let hir::TyKind::Path(ty_path) = ty_kind + && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path + && let Some(func_ty) = func_hir_id_to_func_ty(cx, init.hir_id) + && let Some(return_type) = func_ty_to_return_type(cx, func_ty) + && is_same_type(cx, resolved_path_ty.res, if is_ref { + return_type.peel_refs() + } else { + return_type + }) +======= + if let hir::TyKind::Path(ty_path) = &ty.kind + && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path +======= + let mut is_ref = false; + let mut ty_kind = &ty.kind; +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + + // If the annotation is a ref we "peel" it + if let hir::TyKind::Ref(_, mut_ty) = &ty.kind { + is_ref = true; + ty_kind = &mut_ty.ty.kind; + } + + if let hir::TyKind::Path(ty_path) = ty_kind + && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path + && let Some(func_ty) = func_hir_id_to_func_ty(cx, init.hir_id) + && let Some(return_type) = func_ty_to_return_type(cx, func_ty) +<<<<<<< HEAD + && is_same_type(cx, resolved_path_ty.res, return_type) +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + && is_same_type(cx, resolved_path_ty.res, if is_ref { + return_type.peel_refs() + } else { + return_type + }) +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + { + span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation"); + } + }, + // When the initialization is a path for example u32::MAX + hir::ExprKind::Path(init_path) => { + // TODO: check for non primty +<<<<<<< HEAD +<<<<<<< HEAD + if let Some(primty) = extract_primty(&ty.kind) + + && let hir::QPath::TypeRelative(init_ty, _) = init_path + && let Some(primty_init) = extract_primty(&init_ty.kind) +======= + if let hir::TyKind::Path(ty_path) = &ty.kind + && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path + && let hir::def::Res::PrimTy(primty) = resolved_path_ty.res + + && let hir::QPath::TypeRelative(init_ty, _) = init_path + && let hir::TyKind::Path(init_ty_path) = &init_ty.kind + && let hir::QPath::Resolved(_, resolved_init_ty_path) = init_ty_path + && let hir::def::Res::PrimTy(primty_init) = resolved_init_ty_path.res +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + if let Some(primty) = extract_primty(&ty.kind) + + && let hir::QPath::TypeRelative(init_ty, _) = init_path + && let Some(primty_init) = extract_primty(&init_ty.kind) +>>>>>>> 6f26df1c9 (Extract common logic to function) + + && primty == primty_init + { + span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation"); + } + }, + hir::ExprKind::Lit(init_lit) => { + match init_lit.node { + // In these cases the annotation is redundant + LitKind::Str(..) + | LitKind::ByteStr(..) + | LitKind::Byte(..) + | LitKind::Char(..) + | LitKind::Bool(..) + | LitKind::CStr(..) => { + span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation"); + }, + LitKind::Int(..) | LitKind::Float(..) => { + // If the initialization value is a suffixed literal we lint + if init_lit.node.is_suffixed() { + span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation"); + } + }, + LitKind::Err => (), + } + } + _ => () + } + }; + } +} diff --git a/clippy_lints/src/ref_patterns.rs b/clippy_lints/src/ref_patterns.rs new file mode 100644 index 000000000000..b1530eed1c11 --- /dev/null +++ b/clippy_lints/src/ref_patterns.rs @@ -0,0 +1,44 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use rustc_ast::ast::{BindingAnnotation, Pat, PatKind}; +use rustc_lint::{EarlyContext, EarlyLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for usages of the `ref` keyword. + /// ### Why is this bad? + /// The `ref` keyword can be confusing for people unfamiliar with it, and often + /// it is more concise to use `&` instead. + /// ### Example + /// ```rust + /// let opt = Some(5); + /// if let Some(ref foo) = opt {} + /// ``` + /// Use instead: + /// ```rust + /// let opt = Some(5); + /// if let Some(foo) = &opt {} + /// ``` + #[clippy::version = "1.71.0"] + pub REF_PATTERNS, + restriction, + "use of a ref pattern, e.g. Some(ref value)" +} +declare_lint_pass!(RefPatterns => [REF_PATTERNS]); + +impl EarlyLintPass for RefPatterns { + fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) { + if let PatKind::Ident(BindingAnnotation::REF, _, _) = pat.kind + && !pat.span.from_expansion() + { + span_lint_and_help( + cx, + REF_PATTERNS, + pat.span, + "usage of ref pattern", + None, + "consider using `&` for clarity instead", + ); + } + } +} diff --git a/clippy_lints/src/reference.rs b/clippy_lints/src/reference.rs index a642e2da3ba1..db870ec4c5b6 100644 --- a/clippy_lints/src/reference.rs +++ b/clippy_lints/src/reference.rs @@ -94,7 +94,7 @@ impl EarlyLintPass for DerefAddrOf { DEREF_ADDROF, e.span, "immediately dereferencing a reference", - "try this", + "try", sugg.to_string(), applicability, ); diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index 9e6c6c73d4fe..de336898e767 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -3,12 +3,12 @@ use std::fmt::Display; use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; use clippy_utils::source::snippet_opt; -use clippy_utils::{match_def_path, paths}; -use if_chain::if_chain; +use clippy_utils::{def_path_def_ids, path_def_id, paths}; use rustc_ast::ast::{LitKind, StrStyle}; +use rustc_hir::def_id::DefIdMap; use rustc_hir::{BorrowKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::{BytePos, Span}; declare_clippy_lint! { @@ -55,26 +55,52 @@ declare_clippy_lint! { "trivial regular expressions" } -declare_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX]); +#[derive(Copy, Clone)] +enum RegexKind { + Unicode, + UnicodeSet, + Bytes, + BytesSet, +} + +#[derive(Default)] +pub struct Regex { + definitions: DefIdMap, +} + +impl_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX]); impl<'tcx> LateLintPass<'tcx> for Regex { + fn check_crate(&mut self, cx: &LateContext<'tcx>) { + // We don't use `match_def_path` here because that relies on matching the exact path, which changed + // between regex 1.8 and 1.9 + // + // `def_path_def_ids` will resolve through re-exports but is relatively heavy, so we only perform + // the operation once and store the results + let mut resolve = |path, kind| { + for id in def_path_def_ids(cx, path) { + self.definitions.insert(id, kind); + } + }; + + resolve(&paths::REGEX_NEW, RegexKind::Unicode); + resolve(&paths::REGEX_BUILDER_NEW, RegexKind::Unicode); + resolve(&paths::REGEX_SET_NEW, RegexKind::UnicodeSet); + resolve(&paths::REGEX_BYTES_NEW, RegexKind::Bytes); + resolve(&paths::REGEX_BYTES_BUILDER_NEW, RegexKind::Bytes); + resolve(&paths::REGEX_BYTES_SET_NEW, RegexKind::BytesSet); + } + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if_chain! { - if let ExprKind::Call(fun, [arg]) = expr.kind; - if let ExprKind::Path(ref qpath) = fun.kind; - if let Some(def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id(); - then { - if match_def_path(cx, def_id, &paths::REGEX_NEW) || - match_def_path(cx, def_id, &paths::REGEX_BUILDER_NEW) { - check_regex(cx, arg, true); - } else if match_def_path(cx, def_id, &paths::REGEX_BYTES_NEW) || - match_def_path(cx, def_id, &paths::REGEX_BYTES_BUILDER_NEW) { - check_regex(cx, arg, false); - } else if match_def_path(cx, def_id, &paths::REGEX_SET_NEW) { - check_set(cx, arg, true); - } else if match_def_path(cx, def_id, &paths::REGEX_BYTES_SET_NEW) { - check_set(cx, arg, false); - } + if let ExprKind::Call(fun, [arg]) = expr.kind + && let Some(def_id) = path_def_id(cx, fun) + && let Some(regex_kind) = self.definitions.get(&def_id) + { + match regex_kind { + RegexKind::Unicode => check_regex(cx, arg, true), + RegexKind::UnicodeSet => check_set(cx, arg, true), + RegexKind::Bytes => check_regex(cx, arg, false), + RegexKind::BytesSet => check_set(cx, arg, false), } } } @@ -122,37 +148,39 @@ fn lint_syntax_error(cx: &LateContext<'_>, error: ®ex_syntax::Error, unescape } fn const_str<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option { - constant(cx, cx.typeck_results(), e).and_then(|(c, _)| match c { + constant(cx, cx.typeck_results(), e).and_then(|c| match c { Constant::Str(s) => Some(s), _ => None, }) } fn is_trivial_regex(s: ®ex_syntax::hir::Hir) -> Option<&'static str> { - use regex_syntax::hir::Anchor::{EndText, StartText}; - use regex_syntax::hir::HirKind::{Alternation, Anchor, Concat, Empty, Literal}; + use regex_syntax::hir::HirKind::{Alternation, Concat, Empty, Literal, Look}; + use regex_syntax::hir::Look as HirLook; let is_literal = |e: &[regex_syntax::hir::Hir]| e.iter().all(|e| matches!(*e.kind(), Literal(_))); match *s.kind() { - Empty | Anchor(_) => Some("the regex is unlikely to be useful as it is"), + Empty | Look(_) => Some("the regex is unlikely to be useful as it is"), Literal(_) => Some("consider using `str::contains`"), Alternation(ref exprs) => { - if exprs.iter().all(|e| e.kind().is_empty()) { + if exprs.iter().all(|e| matches!(e.kind(), Empty)) { Some("the regex is unlikely to be useful as it is") } else { None } }, Concat(ref exprs) => match (exprs[0].kind(), exprs[exprs.len() - 1].kind()) { - (&Anchor(StartText), &Anchor(EndText)) if exprs[1..(exprs.len() - 1)].is_empty() => { + (&Look(HirLook::Start), &Look(HirLook::End)) if exprs[1..(exprs.len() - 1)].is_empty() => { Some("consider using `str::is_empty`") }, - (&Anchor(StartText), &Anchor(EndText)) if is_literal(&exprs[1..(exprs.len() - 1)]) => { + (&Look(HirLook::Start), &Look(HirLook::End)) if is_literal(&exprs[1..(exprs.len() - 1)]) => { Some("consider using `==` on `str`s") }, - (&Anchor(StartText), &Literal(_)) if is_literal(&exprs[1..]) => Some("consider using `str::starts_with`"), - (&Literal(_), &Anchor(EndText)) if is_literal(&exprs[1..(exprs.len() - 1)]) => { + (&Look(HirLook::Start), &Literal(_)) if is_literal(&exprs[1..]) => { + Some("consider using `str::starts_with`") + }, + (&Literal(_), &Look(HirLook::End)) if is_literal(&exprs[1..(exprs.len() - 1)]) => { Some("consider using `str::ends_with`") }, _ if is_literal(exprs) => Some("consider using `str::contains`"), @@ -175,10 +203,15 @@ fn check_set<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, utf8: bool) { } fn check_regex<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, utf8: bool) { - let mut parser = regex_syntax::ParserBuilder::new() - .unicode(true) - .allow_invalid_utf8(!utf8) - .build(); +<<<<<<< HEAD +<<<<<<< HEAD + let mut parser = regex_syntax::ParserBuilder::new().unicode(true).utf8(utf8).build(); +======= + let mut parser = regex_syntax::ParserBuilder::new().unicode(true).utf8(!utf8).build(); +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + let mut parser = regex_syntax::ParserBuilder::new().unicode(true).utf8(utf8).build(); +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) if let ExprKind::Lit(ref lit) = expr.kind { if let LitKind::Str(ref r, style) = lit.node { diff --git a/clippy_lints/src/renamed_lints.rs b/clippy_lints/src/renamed_lints.rs index 9f487dedb8cb..5f3f8cc2459c 100644 --- a/clippy_lints/src/renamed_lints.rs +++ b/clippy_lints/src/renamed_lints.rs @@ -15,6 +15,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[ ("clippy::eval_order_dependence", "clippy::mixed_read_write_in_expression"), ("clippy::identity_conversion", "clippy::useless_conversion"), ("clippy::if_let_some_result", "clippy::match_result_ok"), + ("clippy::integer_arithmetic", "clippy::arithmetic_side_effects"), ("clippy::logic_bug", "clippy::overly_complex_bool_expr"), ("clippy::new_without_default_derive", "clippy::new_without_default"), ("clippy::option_and_then_some", "clippy::bind_instead_of_map"), @@ -30,18 +31,32 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[ ("clippy::stutter", "clippy::module_name_repetitions"), ("clippy::to_string_in_display", "clippy::recursive_format_impl"), ("clippy::zero_width_space", "clippy::invisible_characters"), +<<<<<<< HEAD + ("clippy::cast_ref_to_mut", "cast_ref_to_mut"), + ("clippy::clone_double_ref", "suspicious_double_ref_op"), + ("clippy::cmp_nan", "invalid_nan_comparisons"), +======= + ("clippy::clone_double_ref", "suspicious_double_ref_op"), +>>>>>>> e4f5d83fa (Fixed formatting.) ("clippy::drop_bounds", "drop_bounds"), + ("clippy::drop_copy", "dropping_copy_types"), + ("clippy::drop_ref", "dropping_references"), ("clippy::for_loop_over_option", "for_loops_over_fallibles"), ("clippy::for_loop_over_result", "for_loops_over_fallibles"), ("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"), + ("clippy::forget_copy", "forgetting_copy_types"), + ("clippy::forget_ref", "forgetting_references"), + ("clippy::fn_null_check", "incorrect_fn_null_checks"), ("clippy::into_iter_on_array", "array_into_iter"), ("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"), ("clippy::invalid_ref", "invalid_value"), + ("clippy::invalid_utf8_in_unchecked", "invalid_from_utf8_unchecked"), ("clippy::let_underscore_drop", "let_underscore_drop"), ("clippy::mem_discriminant_non_enum", "enum_intrinsics_non_enums"), ("clippy::panic_params", "non_fmt_panics"), ("clippy::positional_named_format_parameters", "named_arguments_used_positionally"), ("clippy::temporary_cstring_as_ptr", "temporary_cstring_as_ptr"), + ("clippy::undropped_manually_drops", "undropped_manually_drops"), ("clippy::unknown_clippy_lints", "unknown_lints"), ("clippy::unused_label", "unused_labels"), ]; diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index df126d7617eb..9957711d5a33 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::source::{snippet_opt, snippet_with_context}; -use clippy_utils::visitors::{for_each_expr, Descend}; +use clippy_utils::visitors::{for_each_expr_with_closures, Descend}; use clippy_utils::{fn_def_id, path_to_local_id, span_find_starting_semi}; use core::ops::ControlFlow; use if_chain::if_chain; @@ -9,7 +9,8 @@ use rustc_hir::intravisit::FnKind; use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, LangItem, MatchSource, PatKind, QPath, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, subst::GenericArgKind, Ty}; +use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; use rustc_span::source_map::Span; @@ -25,6 +26,20 @@ declare_clippy_lint! { /// It is just extraneous code. Remove it to make your code /// more rusty. /// + /// ### Known problems + /// In the case of some temporaries, e.g. locks, eliding the variable binding could lead +<<<<<<< HEAD +<<<<<<< HEAD + /// to deadlocks. See [this issue](https://github.com/rust-lang/rust/issues/37612). +======= + /// to deadlocks. See [rust-lang issue 37612](https://github.com/rust-lang/rust/issues/37612). +>>>>>>> 62eb4e7d7 (Bring up Rust lang #37612 as a known problem for let_and_return) +======= + /// to deadlocks. See [this issue](https://github.com/rust-lang/rust/issues/37612). +>>>>>>> 6f2497703 (Compact issue link) + /// This could become relevant if the code is later changed to use the code that would have been + /// bound without first assigning it to a let-binding. + /// /// ### Example /// ```rust /// fn foo() -> String { @@ -70,7 +85,7 @@ declare_clippy_lint! { "using a return statement like `return expr;` where an expression would suffice" } -#[derive(PartialEq, Eq, Clone)] +#[derive(PartialEq, Eq)] enum RetReplacement<'tcx> { Empty, Block, @@ -80,7 +95,7 @@ enum RetReplacement<'tcx> { } impl<'tcx> RetReplacement<'tcx> { - fn sugg_help(self) -> &'static str { + fn sugg_help(&self) -> &'static str { match self { Self::Empty | Self::Expr(..) => "remove `return`", Self::Block => "replace `return` with an empty block", @@ -88,10 +103,11 @@ impl<'tcx> RetReplacement<'tcx> { Self::IfSequence(..) => "remove `return` and wrap the sequence with parentheses", } } - fn applicability(&self) -> Option { + + fn applicability(&self) -> Applicability { match self { - Self::Expr(_, ap) | Self::IfSequence(_, ap) => Some(*ap), - _ => None, + Self::Expr(_, ap) | Self::IfSequence(_, ap) => *ap, + _ => Applicability::MachineApplicable, } } } @@ -271,7 +287,7 @@ fn check_final_expr<'tcx>( return; } - emit_return_lint(cx, ret_span, semi_spans, replacement); + emit_return_lint(cx, ret_span, semi_spans, &replacement); }, ExprKind::If(_, then, else_clause_opt) => { check_block_return(cx, &then.kind, peeled_drop_expr.span, semi_spans.clone()); @@ -285,7 +301,7 @@ fn check_final_expr<'tcx>( // (except for unit type functions) so we don't match it ExprKind::Match(_, arms, MatchSource::Normal) => { let match_ty = cx.typeck_results().expr_ty(peeled_drop_expr); - for arm in arms.iter() { + for arm in *arms { check_final_expr(cx, arm.body, semi_spans.clone(), RetReplacement::Unit, Some(match_ty)); } }, @@ -306,25 +322,22 @@ fn expr_contains_conjunctive_ifs<'tcx>(expr: &'tcx Expr<'tcx>) -> bool { contains_if(expr, false) } -fn emit_return_lint(cx: &LateContext<'_>, ret_span: Span, semi_spans: Vec, replacement: RetReplacement<'_>) { +fn emit_return_lint(cx: &LateContext<'_>, ret_span: Span, semi_spans: Vec, replacement: &RetReplacement<'_>) { if ret_span.from_expansion() { return; } - let applicability = replacement.applicability().unwrap_or(Applicability::MachineApplicable); - let return_replacement = replacement.to_string(); - let sugg_help = replacement.sugg_help(); span_lint_and_then(cx, NEEDLESS_RETURN, ret_span, "unneeded `return` statement", |diag| { - diag.span_suggestion_hidden(ret_span, sugg_help, return_replacement, applicability); - // for each parent statement, we need to remove the semicolon - for semi_stmt_span in semi_spans { - diag.tool_only_span_suggestion(semi_stmt_span, "remove this semicolon", "", applicability); - } + let suggestions = std::iter::once((ret_span, replacement.to_string())) + .chain(semi_spans.into_iter().map(|span| (span, String::new()))) + .collect(); + + diag.multipart_suggestion_verbose(replacement.sugg_help(), suggestions, replacement.applicability()); }); } fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { - for_each_expr(expr, |e| { + for_each_expr_with_closures(cx, expr, |e| { if let Some(def_id) = fn_def_id(cx, e) && cx .tcx @@ -333,7 +346,7 @@ fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) .skip_binder() .output() .walk() - .any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(_))) + .any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(re) if !re.is_static())) { ControlFlow::Break(()) } else { diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs index 34a3e5ddf4f6..d345db88e2b2 100644 --- a/clippy_lints/src/semicolon_block.rs +++ b/clippy_lints/src/semicolon_block.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and use rustc_errors::Applicability; use rustc_hir::{Block, Expr, ExprKind, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Span; declare_clippy_lint! { @@ -64,7 +64,203 @@ declare_clippy_lint! { restriction, "add a semicolon outside the block" } -declare_lint_pass!(SemicolonBlock => [SEMICOLON_INSIDE_BLOCK, SEMICOLON_OUTSIDE_BLOCK]); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +impl_lint_pass!(SemicolonBlock => [SEMICOLON_INSIDE_BLOCK, SEMICOLON_OUTSIDE_BLOCK]); + +#[derive(Copy, Clone)] +pub struct SemicolonBlock { +<<<<<<< HEAD +<<<<<<< HEAD + semicolon_inside_block_ignore_singleline: bool, + semicolon_outside_block_ignore_multiline: bool, +} + +impl SemicolonBlock { + pub fn new(semicolon_inside_block_ignore_singleline: bool, semicolon_outside_block_ignore_multiline: bool) -> Self { + Self { + semicolon_inside_block_ignore_singleline, + semicolon_outside_block_ignore_multiline, + } + } + + fn semicolon_inside_block(self, cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<'_>, semi_span: Span) { + let insert_span = tail.span.source_callsite().shrink_to_hi(); + let remove_span = semi_span.with_lo(block.span.hi()); + + if self.semicolon_inside_block_ignore_singleline && get_line(cx, remove_span) == get_line(cx, insert_span) { + return; + } + + span_lint_and_then( + cx, + SEMICOLON_INSIDE_BLOCK, + semi_span, + "consider moving the `;` inside the block for consistent formatting", + |diag| { + multispan_sugg_with_applicability( + diag, + "put the `;` here", + Applicability::MachineApplicable, + [(remove_span, String::new()), (insert_span, ";".to_owned())], + ); + }, + ); + } + + fn semicolon_outside_block( + self, + cx: &LateContext<'_>, + block: &Block<'_>, + tail_stmt_expr: &Expr<'_>, + semi_span: Span, + ) { + let insert_span = block.span.with_lo(block.span.hi()); + // account for macro calls + let semi_span = cx.sess().source_map().stmt_span(semi_span, block.span); + let remove_span = semi_span.with_lo(tail_stmt_expr.span.source_callsite().hi()); + + if self.semicolon_outside_block_ignore_multiline && get_line(cx, remove_span) != get_line(cx, insert_span) { + return; + } + + span_lint_and_then( + cx, + SEMICOLON_OUTSIDE_BLOCK, + block.span, + "consider moving the `;` outside the block for consistent formatting", + |diag| { + multispan_sugg_with_applicability( + diag, + "put the `;` here", + Applicability::MachineApplicable, + [(remove_span, String::new()), (insert_span, ";".to_owned())], + ); + }, + ); + } +} +======= +declare_clippy_lint! { + /// ### What it does + /// + /// Suggests moving the semicolon from a block's final expression outside of + /// the block if it's singleline, and inside the block if it's multiline. + /// + /// ### Why is this bad? + /// + /// Some may prefer if the semicolon is outside of a block if it is only one + /// expression, as this allows rustfmt to make it singleline (and may just be + /// more readable). In the case that it isn't, it should be inside. + /// Take a look at both `semicolon_inside_block` and `semicolon_outside_block` + /// for alternatives. + /// + /// ### Example + /// + /// ```rust + /// # fn f(_: u32) {} + /// # let x = 0; + /// unsafe { f(x); } + /// + /// unsafe { + /// let x = 1; + /// f(x) + /// }; + /// ``` + /// Use instead: + /// ```rust + /// # fn f(_: u32) {} + /// # let x = 0; + /// unsafe { f(x) }; + /// + /// unsafe { + /// let x = 1; + /// f(x); + /// } + /// ``` + #[clippy::version = "1.68.0"] + pub SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE, + restriction, + "add a semicolon inside the block if it's singleline, otherwise outside" +} +declare_lint_pass!(SemicolonBlock => [SEMICOLON_INSIDE_BLOCK, SEMICOLON_OUTSIDE_BLOCK, SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE]); +>>>>>>> 0a81f8257 (add `semicolon_outside_block_if_singleline` lint) +======= + semicolon_inside_block_if_multiline: bool, + semicolon_outside_block_if_singleline: bool, +======= + semicolon_inside_block_ignore_singleline: bool, + semicolon_outside_block_ignore_multiline: bool, +>>>>>>> aa6c27a74 (change names to not be implicitly negative) +} + +impl SemicolonBlock { + pub fn new(semicolon_inside_block_ignore_singleline: bool, semicolon_outside_block_ignore_multiline: bool) -> Self { + Self { + semicolon_inside_block_ignore_singleline, + semicolon_outside_block_ignore_multiline, + } + } + + fn semicolon_inside_block(self, cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<'_>, semi_span: Span) { + let insert_span = tail.span.source_callsite().shrink_to_hi(); + let remove_span = semi_span.with_lo(block.span.hi()); + + if self.semicolon_inside_block_ignore_singleline && get_line(cx, remove_span) == get_line(cx, insert_span) { + return; + } + + span_lint_and_then( + cx, + SEMICOLON_INSIDE_BLOCK, + semi_span, + "consider moving the `;` inside the block for consistent formatting", + |diag| { + multispan_sugg_with_applicability( + diag, + "put the `;` here", + Applicability::MachineApplicable, + [(remove_span, String::new()), (insert_span, ";".to_owned())], + ); + }, + ); + } + + fn semicolon_outside_block( + self, + cx: &LateContext<'_>, + block: &Block<'_>, + tail_stmt_expr: &Expr<'_>, + semi_span: Span, + ) { + let insert_span = block.span.with_lo(block.span.hi()); + // account for macro calls + let semi_span = cx.sess().source_map().stmt_span(semi_span, block.span); + let remove_span = semi_span.with_lo(tail_stmt_expr.span.source_callsite().hi()); + + if self.semicolon_outside_block_ignore_multiline && get_line(cx, remove_span) != get_line(cx, insert_span) { + return; + } + + span_lint_and_then( + cx, + SEMICOLON_OUTSIDE_BLOCK, + block.span, + "consider moving the `;` outside the block for consistent formatting", + |diag| { + multispan_sugg_with_applicability( + diag, + "put the `;` here", + Applicability::MachineApplicable, + [(remove_span, String::new()), (insert_span, ";".to_owned())], + ); + }, + ); + } +} +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) impl LateLintPass<'_> for SemicolonBlock { fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) { @@ -83,21 +279,94 @@ impl LateLintPass<'_> for SemicolonBlock { span, .. } = stmt else { return }; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + self.semicolon_outside_block(cx, block, expr, span); +======= semicolon_outside_block(cx, block, expr, span); +<<<<<<< HEAD +<<<<<<< HEAD + semicolon_outside_block_if_singleline_check_outside(cx, block, expr, stmt.span) +>>>>>>> a7c3301b5 (refactor) +======= + semicolon_outside_block_if_singleline_check_outside(cx, block, expr, stmt.span); +>>>>>>> a57445d4d (make cargo test pass, again) +======= +>>>>>>> fa1efa8b1 (refactor) +======= + semicolon_outside_block(self, cx, block, expr, span); +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= + self.semicolon_outside_block(cx, block, expr, span); +>>>>>>> aa6c27a74 (change names to not be implicitly negative) }, StmtKind::Semi(Expr { kind: ExprKind::Block(block @ Block { expr: Some(tail), .. }, _), .. - }) if !block.span.from_expansion() => semicolon_inside_block(cx, block, tail, stmt.span), + }) if !block.span.from_expansion() => { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + self.semicolon_inside_block(cx, block, tail, stmt.span); +======= + semicolon_inside_block(cx, block, tail, stmt.span); +<<<<<<< HEAD +<<<<<<< HEAD + semicolon_outside_block_if_singleline_check_inside(cx, block, tail, stmt.span) +>>>>>>> a7c3301b5 (refactor) +======= + semicolon_outside_block_if_singleline_check_inside(cx, block, tail, stmt.span); +>>>>>>> a57445d4d (make cargo test pass, again) +======= +>>>>>>> fa1efa8b1 (refactor) +======= + semicolon_inside_block(self, cx, block, tail, stmt.span); +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= + self.semicolon_inside_block(cx, block, tail, stmt.span); +>>>>>>> aa6c27a74 (change names to not be implicitly negative) + }, _ => (), } } } -fn semicolon_inside_block(cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<'_>, semi_span: Span) { +<<<<<<< HEAD +<<<<<<< HEAD +fn get_line(cx: &LateContext<'_>, span: Span) -> Option { + if let Ok(line) = cx.sess().source_map().lookup_line(span.lo()) { + return Some(line.line); + } + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + None +======= + check_semicolon_outside_block_if_singleline(cx, block, remove_span, insert_span, true, "inside"); + +======= +>>>>>>> a7c3301b5 (refactor) +======= + semicolon_outside_block_if_singleline(cx, block, remove_span, insert_span, true, "inside"); +======= +fn semicolon_inside_block( + conf: &mut SemicolonBlock, + cx: &LateContext<'_>, + block: &Block<'_>, + tail: &Expr<'_>, + semi_span: Span, +) { let insert_span = tail.span.source_callsite().shrink_to_hi(); let remove_span = semi_span.with_lo(block.span.hi()); + if conf.semicolon_inside_block_if_multiline && get_line(cx, remove_span) == get_line(cx, insert_span) { + return; + } +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) + +>>>>>>> fa1efa8b1 (refactor) span_lint_and_then( cx, SEMICOLON_INSIDE_BLOCK, @@ -114,12 +383,22 @@ fn semicolon_inside_block(cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<' ); } -fn semicolon_outside_block(cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_expr: &Expr<'_>, semi_span: Span) { +fn semicolon_outside_block( + conf: &mut SemicolonBlock, + cx: &LateContext<'_>, + block: &Block<'_>, + tail_stmt_expr: &Expr<'_>, + semi_span: Span, +) { let insert_span = block.span.with_lo(block.span.hi()); // account for macro calls let semi_span = cx.sess().source_map().stmt_span(semi_span, block.span); let remove_span = semi_span.with_lo(tail_stmt_expr.span.source_callsite().hi()); + if conf.semicolon_outside_block_if_singleline && get_line(cx, remove_span) != get_line(cx, insert_span) { + return; + } + span_lint_and_then( cx, SEMICOLON_OUTSIDE_BLOCK, @@ -134,4 +413,15 @@ fn semicolon_outside_block(cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_ex ); }, ); +>>>>>>> 0a81f8257 (add `semicolon_outside_block_if_singleline` lint) +} + +======= +>>>>>>> aa6c27a74 (change names to not be implicitly negative) +fn get_line(cx: &LateContext<'_>, span: Span) -> Option { + if let Ok(line) = cx.sess().source_map().lookup_line(span.lo()) { + return Some(line.line); + } + + None } diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index ae7d19624ba6..993f9373d85d 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for Shadow { fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) { let PatKind::Binding(_, id, ident, _) = pat.kind else { return }; - if pat.span.desugaring_kind().is_some() { + if pat.span.desugaring_kind().is_some() || pat.span.from_expansion() { return; } diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs index 869358fb1ba7..80564ba8c3c1 100644 --- a/clippy_lints/src/significant_drop_tightening.rs +++ b/clippy_lints/src/significant_drop_tightening.rs @@ -1,23 +1,23 @@ -use clippy_utils::{ - diagnostics::span_lint_and_then, - get_attr, - source::{indent_of, snippet}, -}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{Applicability, Diagnostic}; -use rustc_hir::{ - self as hir, - intravisit::{walk_expr, Visitor}, -}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::source::{indent_of, snippet}; +use clippy_utils::{expr_or_init, get_attr, path_to_local}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; +use rustc_errors::Applicability; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::intravisit::{walk_expr, Visitor}; +use rustc_hir::{self as hir}; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::ty::{subst::GenericArgKind, Ty, TypeAndMut}; +use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::{Ty, TypeAndMut}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{symbol::Ident, Span, DUMMY_SP}; +use rustc_span::symbol::Ident; +use rustc_span::{sym, Span, DUMMY_SP}; +use std::borrow::Cow; declare_clippy_lint! { /// ### What it does /// - /// Searches for elements marked with `#[clippy::significant_drop]` that could be early + /// Searches for elements marked with `#[clippy::has_significant_drop]` that could be early /// dropped but are in fact dropped at the end of their scopes. In other words, enforces the /// "tightening" of their possible lifetimes. /// @@ -46,7 +46,7 @@ declare_clippy_lint! { /// do_heavy_computation_that_takes_time(owned_rslt); /// } /// ``` - #[clippy::version = "1.67.0"] + #[clippy::version = "1.69.0"] pub SIGNIFICANT_DROP_TIGHTENING, nursery, "Searches for elements marked with `#[clippy::has_significant_drop]` that could be early dropped but are in fact dropped at the end of their scopes" @@ -56,255 +56,128 @@ impl_lint_pass!(SignificantDropTightening<'_> => [SIGNIFICANT_DROP_TIGHTENING]); #[derive(Default)] pub struct SignificantDropTightening<'tcx> { + apas: FxIndexMap, /// Auxiliary structure used to avoid having to verify the same type multiple times. seen_types: FxHashSet>, type_cache: FxHashMap, bool>, } -impl<'tcx> SignificantDropTightening<'tcx> { - /// Unifies the statements of a block with its return expression. - fn all_block_stmts<'ret, 'rslt, 'stmts>( - block_stmts: &'stmts [hir::Stmt<'tcx>], - dummy_ret_stmt: Option<&'ret hir::Stmt<'tcx>>, - ) -> impl Iterator> - where - 'ret: 'rslt, - 'stmts: 'rslt, - { - block_stmts.iter().chain(dummy_ret_stmt) - } - - /// Searches for at least one statement that could slow down the release of a significant drop. - fn at_least_one_stmt_is_expensive<'stmt>(stmts: impl Iterator>) -> bool - where - 'tcx: 'stmt, - { - for stmt in stmts { - match stmt.kind { - hir::StmtKind::Expr(expr) if let hir::ExprKind::Path(_) = expr.kind => {} - hir::StmtKind::Local(local) if let Some(expr) = local.init - && let hir::ExprKind::Path(_) = expr.kind => {}, - _ => return true - }; - } - false - } - - /// Verifies if the expression is of type `drop(some_lock_path)` to assert that the temporary - /// is already being dropped before the end of its scope. - fn has_drop(expr: &'tcx hir::Expr<'_>, init_bind_ident: Ident) -> bool { - if let hir::ExprKind::Call(fun, args) = expr.kind - && let hir::ExprKind::Path(hir::QPath::Resolved(_, fun_path)) = &fun.kind - && let [fun_ident, ..] = fun_path.segments - && fun_ident.ident.name == rustc_span::sym::drop - && let [first_arg, ..] = args - && let hir::ExprKind::Path(hir::QPath::Resolved(_, arg_path)) = &first_arg.kind - && let [first_arg_ps, .. ] = arg_path.segments - { - first_arg_ps.ident == init_bind_ident - } - else { - false - } - } - - /// Tries to find types marked with `#[has_significant_drop]` of an expression `expr` that is - /// originated from `stmt` and then performs common logic on `sdap`. - fn modify_sdap_if_sig_drop_exists( +impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> { + fn check_fn( &mut self, cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'_>, - idx: usize, - sdap: &mut SigDropAuxParams, - stmt: &hir::Stmt<'_>, - cb: impl Fn(&mut SigDropAuxParams), + _: hir::intravisit::FnKind<'_>, + _: &hir::FnDecl<'_>, + body: &'tcx hir::Body<'_>, + _: Span, + _: hir::def_id::LocalDefId, ) { - let mut sig_drop_finder = SigDropFinder::new(cx, &mut self.seen_types, &mut self.type_cache); - sig_drop_finder.visit_expr(expr); - if sig_drop_finder.has_sig_drop { - cb(sdap); - if sdap.number_of_stmts > 0 { - sdap.last_use_stmt_idx = idx; - sdap.last_use_stmt_span = stmt.span; - if let hir::ExprKind::MethodCall(_, _, _, span) = expr.kind { - sdap.last_use_method_span = span; - } + self.apas.clear(); +<<<<<<< HEAD +<<<<<<< HEAD + let initial_dummy_stmt = dummy_stmt_expr(body.value); +======= + let initial_dummy_stmt = dummy_stmt_expr(&body.value); +>>>>>>> f0619024b (Fix #10413) +======= + let initial_dummy_stmt = dummy_stmt_expr(body.value); +>>>>>>> fc832f0eb (Dogfood) + let mut ap = AuxParams::new(&mut self.apas, &initial_dummy_stmt); + StmtsChecker::new(&mut ap, cx, &mut self.seen_types, &mut self.type_cache).visit_body(body); + for apa in ap.apas.values() { + if apa.counter <= 1 || !apa.has_expensive_expr_after_last_attr { + continue; } - sdap.number_of_stmts = sdap.number_of_stmts.wrapping_add(1); - } - } - - /// Shows generic overall messages as well as specialized messages depending on the usage. - fn set_suggestions(cx: &LateContext<'tcx>, block_span: Span, diag: &mut Diagnostic, sdap: &SigDropAuxParams) { - match sdap.number_of_stmts { - 0 | 1 => {}, - 2 => { - let indent = " ".repeat(indent_of(cx, sdap.last_use_stmt_span).unwrap_or(0)); - let init_method = snippet(cx, sdap.init_method_span, ".."); - let usage_method = snippet(cx, sdap.last_use_method_span, ".."); - let stmt = if let Some(last_use_bind_span) = sdap.last_use_bind_span { - format!( - "\n{indent}let {} = {init_method}.{usage_method};", - snippet(cx, last_use_bind_span, ".."), - ) - } else { - format!("\n{indent}{init_method}.{usage_method};") - }; - diag.span_suggestion_verbose( - sdap.init_stmt_span, - "merge the temporary construction with its single usage", - stmt, - Applicability::MaybeIncorrect, - ); - diag.span_suggestion( - sdap.last_use_stmt_span, - "remove separated single usage", - "", - Applicability::MaybeIncorrect, - ); - }, - _ => { - diag.span_suggestion( - sdap.last_use_stmt_span.shrink_to_hi(), - "drop the temporary after the end of its last usage", - format!( - "\n{}drop({});", - " ".repeat(indent_of(cx, sdap.last_use_stmt_span).unwrap_or(0)), - sdap.init_bind_ident - ), - Applicability::MaybeIncorrect, - ); - }, - } - diag.note("this might lead to unnecessary resource contention"); - diag.span_label( - block_span, - format!( - "temporary `{}` is currently being dropped at the end of its contained scope", - sdap.init_bind_ident - ), - ); - } -} - -impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> { - fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) { - let dummy_ret_stmt = block.expr.map(|expr| hir::Stmt { - hir_id: hir::HirId::INVALID, - kind: hir::StmtKind::Expr(expr), - span: DUMMY_SP, - }); - let mut sdap = SigDropAuxParams::default(); - for (idx, stmt) in Self::all_block_stmts(block.stmts, dummy_ret_stmt.as_ref()).enumerate() { - match stmt.kind { - hir::StmtKind::Expr(expr) => self.modify_sdap_if_sig_drop_exists( - cx, - expr, - idx, - &mut sdap, - stmt, - |_| {} - ), - hir::StmtKind::Local(local) if let Some(expr) = local.init => self.modify_sdap_if_sig_drop_exists( - cx, - expr, - idx, - &mut sdap, - stmt, - |local_sdap| { - if local_sdap.number_of_stmts == 0 { - if let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind { - local_sdap.init_bind_ident = ident; - } - if let hir::ExprKind::MethodCall(_, local_expr, _, span) = expr.kind { - local_sdap.init_method_span = local_expr.span.to(span); - } - local_sdap.init_stmt_span = stmt.span; - } - else if let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind { - local_sdap.last_use_bind_span = Some(ident.span); - } - } - ), - hir::StmtKind::Semi(expr) => { - if Self::has_drop(expr, sdap.init_bind_ident) { - return; - } - self.modify_sdap_if_sig_drop_exists(cx, expr, idx, &mut sdap, stmt, |_| {}); - }, - _ => {} - }; - } - - let idx = sdap.last_use_stmt_idx.wrapping_add(1); - let stmts_after_last_use = Self::all_block_stmts(block.stmts, dummy_ret_stmt.as_ref()).skip(idx); - if sdap.number_of_stmts > 1 && Self::at_least_one_stmt_is_expensive(stmts_after_last_use) { span_lint_and_then( cx, SIGNIFICANT_DROP_TIGHTENING, - sdap.init_bind_ident.span, + apa.first_bind_ident.span, "temporary with significant `Drop` can be early dropped", |diag| { - Self::set_suggestions(cx, block.span, diag, &sdap); + match apa.counter { + 0 | 1 => {}, + 2 => { + let indent = " ".repeat(indent_of(cx, apa.last_stmt_span).unwrap_or(0)); + let init_method = snippet(cx, apa.first_method_span, ".."); + let usage_method = snippet(cx, apa.last_method_span, ".."); +<<<<<<< HEAD +<<<<<<< HEAD + let stmt = if apa.last_bind_ident == Ident::empty() { + format!("\n{indent}{init_method}.{usage_method};") + } else { +======= + let stmt = if apa.last_bind_ident != Ident::empty() { +>>>>>>> f0619024b (Fix #10413) +======= + let stmt = if apa.last_bind_ident == Ident::empty() { + format!("\n{indent}{init_method}.{usage_method};") + } else { +>>>>>>> fc832f0eb (Dogfood) + format!( + "\n{indent}let {} = {init_method}.{usage_method};", + snippet(cx, apa.last_bind_ident.span, ".."), + ) +<<<<<<< HEAD +<<<<<<< HEAD +======= + } else { + format!("\n{indent}{init_method}.{usage_method};") +>>>>>>> f0619024b (Fix #10413) +======= +>>>>>>> fc832f0eb (Dogfood) + }; + diag.span_suggestion_verbose( + apa.first_stmt_span, + "merge the temporary construction with its single usage", + stmt, + Applicability::MaybeIncorrect, + ); + diag.span_suggestion( + apa.last_stmt_span, + "remove separated single usage", + "", + Applicability::MaybeIncorrect, + ); + }, + _ => { + diag.span_suggestion( + apa.last_stmt_span.shrink_to_hi(), + "drop the temporary after the end of its last usage", + format!( + "\n{}drop({});", + " ".repeat(indent_of(cx, apa.last_stmt_span).unwrap_or(0)), + apa.first_bind_ident + ), + Applicability::MaybeIncorrect, + ); + }, + } + diag.note("this might lead to unnecessary resource contention"); + diag.span_label( + apa.first_block_span, + format!( + "temporary `{}` is currently being dropped at the end of its contained scope", + apa.first_bind_ident + ), + ); }, ); } } } -/// Auxiliary parameters used on each block check. -struct SigDropAuxParams { - /// The binding or variable that references the initial construction of the type marked with - /// `#[has_significant_drop]`. - init_bind_ident: Ident, - /// Similar to `init_bind_ident` but encompasses the right-hand method call. - init_method_span: Span, - /// Similar to `init_bind_ident` but encompasses the whole contained statement. - init_stmt_span: Span, - - /// The last visited binding or variable span within a block that had any referenced inner type - /// marked with `#[has_significant_drop]`. - last_use_bind_span: Option, - /// Index of the last visited statement within a block that had any referenced inner type - /// marked with `#[has_significant_drop]`. - last_use_stmt_idx: usize, - /// Similar to `last_use_bind_span` but encompasses the whole contained statement. - last_use_stmt_span: Span, - /// Similar to `last_use_bind_span` but encompasses the right-hand method call. - last_use_method_span: Span, - - /// Total number of statements within a block that have any referenced inner type marked with - /// `#[has_significant_drop]`. - number_of_stmts: usize, -} - -impl Default for SigDropAuxParams { - fn default() -> Self { - Self { - init_bind_ident: Ident::empty(), - init_method_span: DUMMY_SP, - init_stmt_span: DUMMY_SP, - last_use_bind_span: None, - last_use_method_span: DUMMY_SP, - last_use_stmt_idx: 0, - last_use_stmt_span: DUMMY_SP, - number_of_stmts: 0, - } - } -} - -/// Checks the existence of the `#[has_significant_drop]` attribute -struct SigDropChecker<'cx, 'sdt, 'tcx> { +/// Checks the existence of the `#[has_significant_drop]` attribute. +struct AttrChecker<'cx, 'others, 'tcx> { cx: &'cx LateContext<'tcx>, - seen_types: &'sdt mut FxHashSet>, - type_cache: &'sdt mut FxHashMap, bool>, + seen_types: &'others mut FxHashSet>, + type_cache: &'others mut FxHashMap, bool>, } -impl<'cx, 'sdt, 'tcx> SigDropChecker<'cx, 'sdt, 'tcx> { +impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> { pub(crate) fn new( cx: &'cx LateContext<'tcx>, - seen_types: &'sdt mut FxHashSet>, - type_cache: &'sdt mut FxHashMap, bool>, + seen_types: &'others mut FxHashSet>, + type_cache: &'others mut FxHashMap, bool>, ) -> Self { seen_types.clear(); Self { @@ -314,7 +187,17 @@ impl<'cx, 'sdt, 'tcx> SigDropChecker<'cx, 'sdt, 'tcx> { } } - pub(crate) fn has_sig_drop_attr_uncached(&mut self, ty: Ty<'tcx>) -> bool { + fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>) -> bool { + // The borrow checker prevents us from using something fancier like or_insert_with. + if let Some(ty) = self.type_cache.get(&ty) { + return *ty; + } + let value = self.has_sig_drop_attr_uncached(ty); + self.type_cache.insert(ty, value); + value + } + + fn has_sig_drop_attr_uncached(&mut self, ty: Ty<'tcx>) -> bool { if let Some(adt) = ty.ty_adt_def() { let mut iter = get_attr( self.cx.sess(), @@ -333,7 +216,7 @@ impl<'cx, 'sdt, 'tcx> SigDropChecker<'cx, 'sdt, 'tcx> { return true; } } - for generic_arg in b.iter() { + for generic_arg in *b { if let GenericArgKind::Type(ty) = generic_arg.unpack() { if self.has_sig_drop_attr(ty) { return true; @@ -350,73 +233,288 @@ impl<'cx, 'sdt, 'tcx> SigDropChecker<'cx, 'sdt, 'tcx> { } } - pub(crate) fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>) -> bool { - // The borrow checker prevents us from using something fancier like or_insert_with. - if let Some(ty) = self.type_cache.get(&ty) { - return *ty; - } - let value = self.has_sig_drop_attr_uncached(ty); - self.type_cache.insert(ty, value); - value - } - fn has_seen_ty(&mut self, ty: Ty<'tcx>) -> bool { !self.seen_types.insert(ty) } } -/// Performs recursive calls to find any inner type marked with `#[has_significant_drop]`. -struct SigDropFinder<'cx, 'sdt, 'tcx> { - cx: &'cx LateContext<'tcx>, - has_sig_drop: bool, - sig_drop_checker: SigDropChecker<'cx, 'sdt, 'tcx>, +struct StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx> { + ap: &'ap mut AuxParams<'others, 'stmt, 'tcx>, + cx: &'lc LateContext<'tcx>, + seen_types: &'others mut FxHashSet>, + type_cache: &'others mut FxHashMap, bool>, } -impl<'cx, 'sdt, 'tcx> SigDropFinder<'cx, 'sdt, 'tcx> { +impl<'ap, 'lc, 'others, 'stmt, 'tcx> StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx> { fn new( - cx: &'cx LateContext<'tcx>, - seen_types: &'sdt mut FxHashSet>, - type_cache: &'sdt mut FxHashMap, bool>, + ap: &'ap mut AuxParams<'others, 'stmt, 'tcx>, + cx: &'lc LateContext<'tcx>, + seen_types: &'others mut FxHashSet>, + type_cache: &'others mut FxHashMap, bool>, ) -> Self { Self { + ap, cx, - has_sig_drop: false, - sig_drop_checker: SigDropChecker::new(cx, seen_types, type_cache), + seen_types, + type_cache, + } + } + + fn manage_has_expensive_expr_after_last_attr(&mut self) { + let has_expensive_stmt = match self.ap.curr_stmt.kind { + hir::StmtKind::Expr(expr) if !is_expensive_expr(expr) => false, + hir::StmtKind::Local(local) if let Some(expr) = local.init + && let hir::ExprKind::Path(_) = expr.kind => false, + _ => true + }; + if has_expensive_stmt { + for apa in self.ap.apas.values_mut() { + let last_stmt_is_not_dummy = apa.last_stmt_span != DUMMY_SP; + let last_stmt_is_not_curr = self.ap.curr_stmt.span != apa.last_stmt_span; + let block_equals_curr = self.ap.curr_block_hir_id == apa.first_block_hir_id; + let block_is_ancestor = self + .cx + .tcx + .hir() + .parent_iter(self.ap.curr_block_hir_id) + .any(|(id, _)| id == apa.first_block_hir_id); + if last_stmt_is_not_dummy && last_stmt_is_not_curr && (block_equals_curr || block_is_ancestor) { + apa.has_expensive_expr_after_last_attr = true; + } + } } } } -impl<'cx, 'sdt, 'tcx> Visitor<'tcx> for SigDropFinder<'cx, 'sdt, 'tcx> { - fn visit_expr(&mut self, ex: &'tcx hir::Expr<'_>) { - if self - .sig_drop_checker - .has_sig_drop_attr(self.cx.typeck_results().expr_ty(ex)) - { - self.has_sig_drop = true; - return; +impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx> { + fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) { + self.ap.curr_block_hir_id = block.hir_id; + self.ap.curr_block_span = block.span; +<<<<<<< HEAD +<<<<<<< HEAD + for stmt in block.stmts { +======= + for stmt in block.stmts.iter() { +>>>>>>> f0619024b (Fix #10413) +======= + for stmt in block.stmts { +>>>>>>> fc832f0eb (Dogfood) + self.ap.curr_stmt = Cow::Borrowed(stmt); + self.visit_stmt(stmt); + self.ap.curr_block_hir_id = block.hir_id; + self.ap.curr_block_span = block.span; + self.manage_has_expensive_expr_after_last_attr(); + } + if let Some(expr) = block.expr { + self.ap.curr_stmt = Cow::Owned(dummy_stmt_expr(expr)); + self.visit_expr(expr); + self.ap.curr_block_hir_id = block.hir_id; + self.ap.curr_block_span = block.span; + self.manage_has_expensive_expr_after_last_attr(); } + } - match ex.kind { - hir::ExprKind::MethodCall(_, expr, ..) => { - self.visit_expr(expr); - }, - hir::ExprKind::Array(..) - | hir::ExprKind::Assign(..) - | hir::ExprKind::AssignOp(..) - | hir::ExprKind::Binary(..) - | hir::ExprKind::Call(..) - | hir::ExprKind::Field(..) - | hir::ExprKind::If(..) - | hir::ExprKind::Index(..) - | hir::ExprKind::Match(..) - | hir::ExprKind::Repeat(..) - | hir::ExprKind::Ret(..) - | hir::ExprKind::Tup(..) - | hir::ExprKind::Unary(..) - | hir::ExprKind::Yield(..) => { - walk_expr(self, ex); - }, - _ => {}, + fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { + let modify_apa_params = |apa: &mut AuxParamsAttr| { + apa.counter = apa.counter.wrapping_add(1); + apa.has_expensive_expr_after_last_attr = false; + }; + let mut ac = AttrChecker::new(self.cx, self.seen_types, self.type_cache); + if ac.has_sig_drop_attr(self.cx.typeck_results().expr_ty(expr)) { + if let hir::StmtKind::Local(local) = self.ap.curr_stmt.kind + && let hir::PatKind::Binding(_, hir_id, ident, _) = local.pat.kind + && !self.ap.apas.contains_key(&hir_id) + && { + if let Some(local_hir_id) = path_to_local(expr) { + local_hir_id == hir_id + } + else { + true + } + } + { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> fc832f0eb (Dogfood) + let mut apa = AuxParamsAttr { + first_bind_ident: ident, + first_block_hir_id: self.ap.curr_block_hir_id, + first_block_span: self.ap.curr_block_span, + first_method_span: { + let expr_or_init = expr_or_init(self.cx, expr); + if let hir::ExprKind::MethodCall(_, local_expr, _, span) = expr_or_init.kind { + local_expr.span.to(span) + } + else { + expr_or_init.span + } + }, + first_stmt_span: self.ap.curr_stmt.span, + ..Default::default() +<<<<<<< HEAD + }; +======= + let mut apa = AuxParamsAttr::default(); + apa.first_bind_ident = ident; + apa.first_block_hir_id = self.ap.curr_block_hir_id; + apa.first_block_span = self.ap.curr_block_span; + apa.first_method_span = { + let expr_or_init = expr_or_init(self.cx, expr); + if let hir::ExprKind::MethodCall(_, local_expr, _, span) = expr_or_init.kind { + local_expr.span.to(span) + } + else { + expr_or_init.span + } + }; + apa.first_stmt_span = self.ap.curr_stmt.span; +>>>>>>> f0619024b (Fix #10413) +======= + }; +>>>>>>> fc832f0eb (Dogfood) + modify_apa_params(&mut apa); + let _ = self.ap.apas.insert(hir_id, apa); + } else { + let Some(hir_id) = path_to_local(expr) else { return; }; + let Some(apa) = self.ap.apas.get_mut(&hir_id) else { return; }; + match self.ap.curr_stmt.kind { + hir::StmtKind::Local(local) => { + if let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind { + apa.last_bind_ident = ident; + } + if let Some(local_init) = local.init + && let hir::ExprKind::MethodCall(_, _, _, span) = local_init.kind + { + apa.last_method_span = span; + } + }, + hir::StmtKind::Semi(expr) => { + if has_drop(expr, &apa.first_bind_ident, self.cx) { + apa.has_expensive_expr_after_last_attr = false; + apa.last_stmt_span = DUMMY_SP; + return; + } + if let hir::ExprKind::MethodCall(_, _, _, span) = expr.kind { + apa.last_method_span = span; + } + }, + _ => {}, + } + apa.last_stmt_span = self.ap.curr_stmt.span; + modify_apa_params(apa); + } } + walk_expr(self, expr); + } +} + +/// Auxiliary parameters used on each block check of an item +struct AuxParams<'others, 'stmt, 'tcx> { + //// See [AuxParamsAttr]. + apas: &'others mut FxIndexMap, + /// The current block identifier that is being visited. + curr_block_hir_id: hir::HirId, + /// The current block span that is being visited. + curr_block_span: Span, + /// The current statement that is being visited. + curr_stmt: Cow<'stmt, hir::Stmt<'tcx>>, +} + +impl<'others, 'stmt, 'tcx> AuxParams<'others, 'stmt, 'tcx> { + fn new(apas: &'others mut FxIndexMap, curr_stmt: &'stmt hir::Stmt<'tcx>) -> Self { + Self { + apas, + curr_block_hir_id: hir::HirId::INVALID, + curr_block_span: DUMMY_SP, + curr_stmt: Cow::Borrowed(curr_stmt), + } + } +} + +/// Auxiliary parameters used on expression created with `#[has_significant_drop]`. +#[derive(Debug)] +struct AuxParamsAttr { + /// The number of times `#[has_significant_drop]` was referenced. + counter: usize, + /// If an expensive expression follows the last use of anything marked with + /// `#[has_significant_drop]`. + has_expensive_expr_after_last_attr: bool, + + /// The identifier of the block that involves the first `#[has_significant_drop]`. + first_block_hir_id: hir::HirId, + /// The span of the block that involves the first `#[has_significant_drop]`. + first_block_span: Span, + /// The binding or variable that references the initial construction of the type marked with + /// `#[has_significant_drop]`. + first_bind_ident: Ident, + /// Similar to `init_bind_ident` but encompasses the right-hand method call. + first_method_span: Span, + /// Similar to `init_bind_ident` but encompasses the whole contained statement. + first_stmt_span: Span, + + /// The last visited binding or variable span within a block that had any referenced inner type + /// marked with `#[has_significant_drop]`. + last_bind_ident: Ident, + /// Similar to `last_bind_span` but encompasses the right-hand method call. + last_method_span: Span, + /// Similar to `last_bind_span` but encompasses the whole contained statement. + last_stmt_span: Span, +} + +impl Default for AuxParamsAttr { + fn default() -> Self { + Self { + counter: 0, + has_expensive_expr_after_last_attr: false, + first_block_hir_id: hir::HirId::INVALID, + first_bind_ident: Ident::empty(), + first_block_span: DUMMY_SP, + first_method_span: DUMMY_SP, + first_stmt_span: DUMMY_SP, + last_bind_ident: Ident::empty(), + last_method_span: DUMMY_SP, + last_stmt_span: DUMMY_SP, + } + } +} + +fn dummy_stmt_expr<'any>(expr: &'any hir::Expr<'any>) -> hir::Stmt<'any> { + hir::Stmt { + hir_id: hir::HirId::INVALID, + kind: hir::StmtKind::Expr(expr), + span: DUMMY_SP, + } +} + +fn has_drop(expr: &hir::Expr<'_>, first_bind_ident: &Ident, lcx: &LateContext<'_>) -> bool { + if let hir::ExprKind::Call(fun, args) = expr.kind + && let hir::ExprKind::Path(hir::QPath::Resolved(_, fun_path)) = &fun.kind + && let Res::Def(DefKind::Fn, did) = fun_path.res + && lcx.tcx.is_diagnostic_item(sym::mem_drop, did) + && let [first_arg, ..] = args + && let hir::ExprKind::Path(hir::QPath::Resolved(_, arg_path)) = &first_arg.kind + && let [first_arg_ps, .. ] = arg_path.segments + { + &first_arg_ps.ident == first_bind_ident + } + else { + false + } +} + +fn is_expensive_expr(expr: &hir::Expr<'_>) -> bool { +<<<<<<< HEAD +<<<<<<< HEAD + !matches!(expr.kind, hir::ExprKind::Path(_)) +======= + if let hir::ExprKind::Path(_) = expr.kind { + false + } else { + true } +>>>>>>> f0619024b (Fix #10413) +======= + !matches!(expr.kind, hir::ExprKind::Path(_)) +>>>>>>> fc832f0eb (Dogfood) } diff --git a/clippy_lints/src/single_call_fn.rs b/clippy_lints/src/single_call_fn.rs new file mode 100644 index 000000000000..08e0435a2f0f --- /dev/null +++ b/clippy_lints/src/single_call_fn.rs @@ -0,0 +1,176 @@ +use clippy_utils::diagnostics::span_lint_and_help; +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::{is_from_proc_macro, is_in_test_function}; +======= +use clippy_utils::is_from_proc_macro; +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) +======= +use clippy_utils::{is_from_proc_macro, is_in_test_function}; +>>>>>>> 2cd4a9182 (Ignore functions annotated with `#[test]`) +use rustc_data_structures::fx::FxHashMap; +use rustc_hir::def_id::LocalDefId; +use rustc_hir::intravisit::{walk_expr, FnKind, Visitor}; +use rustc_hir::{Body, Expr, ExprKind, FnDecl}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::hir::nested_filter::OnlyBodies; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::Span; + +declare_clippy_lint! { + /// ### What it does +<<<<<<< HEAD +<<<<<<< HEAD + /// Checks for functions that are only used once. Does not lint tests. +======= + /// Checks for functions that are only used once. +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) +======= + /// Checks for functions that are only used once. Does not lint tests. +>>>>>>> 2cd4a9182 (Ignore functions annotated with `#[test]`) + /// + /// ### Why is this bad? + /// It's usually not, splitting a function into multiple parts often improves readability and in + /// the case of generics, can prevent the compiler from duplicating the function dozens of + /// time; instead, only duplicating a thunk. But this can prevent segmentation across a + /// codebase, where many small functions are used only once. + /// + /// Note: If this lint is used, prepare to allow this a lot. + /// + /// ### Example + /// ```rust + /// pub fn a(t: &T) + /// where + /// T: AsRef, + /// { + /// a_inner(t.as_ref()) + /// } + /// + /// fn a_inner(t: &str) { + /// /* snip */ + /// } + /// + /// ``` + /// Use instead: + /// ```rust + /// pub fn a(t: &T) + /// where + /// T: AsRef, + /// { + /// let t = t.as_ref(); + /// /* snip */ + /// } + /// + /// ``` + #[clippy::version = "1.72.0"] + pub SINGLE_CALL_FN, + restriction, + "checks for functions that are only used once" +} +impl_lint_pass!(SingleCallFn => [SINGLE_CALL_FN]); + +#[derive(Clone)] +pub struct SingleCallFn { + pub avoid_breaking_exported_api: bool, + pub def_id_to_usage: FxHashMap)>, +} + +impl<'tcx> LateLintPass<'tcx> for SingleCallFn { + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + kind: FnKind<'tcx>, + _: &'tcx FnDecl<'_>, + body: &'tcx Body<'_>, + span: Span, + def_id: LocalDefId, + ) { + if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) + || in_external_macro(cx.sess(), span) + || is_from_proc_macro(cx, &(&kind, body, cx.tcx.local_def_id_to_hir_id(def_id), span)) +<<<<<<< HEAD +<<<<<<< HEAD + || is_in_test_function(cx.tcx, body.value.hir_id) +======= +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) +======= + || is_in_test_function(cx.tcx, body.value.hir_id) +>>>>>>> 2cd4a9182 (Ignore functions annotated with `#[test]`) + { + return; + } + + self.def_id_to_usage.insert(def_id, (span, vec![])); + } + + fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { + let mut v = FnUsageVisitor { + cx, + def_id_to_usage: &mut self.def_id_to_usage, + }; + cx.tcx.hir().visit_all_item_likes_in_crate(&mut v); + + for usage in self.def_id_to_usage.values() { +<<<<<<< HEAD +<<<<<<< HEAD + let single_call_fn_span = usage.0; + if let [caller_span] = *usage.1 { + span_lint_and_help( + cx, + SINGLE_CALL_FN, + single_call_fn_span, + "this function is only used once", + Some(caller_span), +======= + let fn_span = usage.0; + if let [usage] = *usage.1 { +======= + let single_call_fn_span = usage.0; + if let [caller_span] = *usage.1 { +>>>>>>> a8605269b (add test for closures) + span_lint_and_help( + cx, + SINGLE_CALL_FN, + single_call_fn_span, + "this function is only used once", +<<<<<<< HEAD + Some(usage), +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) +======= + Some(caller_span), +>>>>>>> a8605269b (add test for closures) + "used here", + ); + } + } + } +} + +struct FnUsageVisitor<'a, 'tcx> { + cx: &'a LateContext<'tcx>, + def_id_to_usage: &'a mut FxHashMap)>, +} + +impl<'a, 'tcx> Visitor<'tcx> for FnUsageVisitor<'a, 'tcx> { + type NestedFilter = OnlyBodies; + + fn nested_visit_map(&mut self) -> Self::Map { + self.cx.tcx.hir() + } + + fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { + let Self { cx, .. } = *self; + + if let ExprKind::Path(qpath) = expr.kind + && let res = cx.qpath_res(&qpath, expr.hir_id) + && let Some(call_def_id) = res.opt_def_id() + && let Some(def_id) = call_def_id.as_local() + && let Some(usage) = self.def_id_to_usage.get_mut(&def_id) + { + usage.1.push(expr.span); + } + + walk_expr(self, expr); + } +} diff --git a/clippy_lints/src/single_component_path_imports.rs b/clippy_lints/src/single_component_path_imports.rs index 5743dd21c283..9c21d70c82cc 100644 --- a/clippy_lints/src/single_component_path_imports.rs +++ b/clippy_lints/src/single_component_path_imports.rs @@ -1,11 +1,14 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use rustc_ast::node_id::{NodeId, NodeMap}; +use rustc_ast::ptr::P; use rustc_ast::visit::{walk_expr, Visitor}; -use rustc_ast::{ptr::P, Crate, Expr, ExprKind, Item, ItemKind, MacroDef, ModKind, Ty, TyKind, UseTreeKind}; +use rustc_ast::{Crate, Expr, ExprKind, Item, ItemKind, MacroDef, ModKind, Ty, TyKind, UseTreeKind}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{edition::Edition, symbol::kw, Span, Symbol}; +use rustc_span::edition::Edition; +use rustc_span::symbol::kw; +use rustc_span::{Span, Symbol}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/single_range_in_vec_init.rs b/clippy_lints/src/single_range_in_vec_init.rs new file mode 100644 index 000000000000..76e74b429a64 --- /dev/null +++ b/clippy_lints/src/single_range_in_vec_init.rs @@ -0,0 +1,241 @@ +<<<<<<< HEAD +use clippy_utils::{ +<<<<<<< HEAD +<<<<<<< HEAD + diagnostics::span_lint_and_then, get_trait_def_id, higher::VecArgs, macros::root_macro_call_first_node, + source::snippet_opt, ty::implements_trait, +======= + diagnostics::span_lint_and_then, + get_trait_def_id, + higher::VecArgs, + macros::root_macro_call_first_node, + source::{snippet_opt, snippet_with_applicability}, + ty::implements_trait, +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= + diagnostics::span_lint_and_then, get_trait_def_id, higher::VecArgs, macros::root_macro_call_first_node, + source::snippet_opt, ty::implements_trait, +>>>>>>> 830d307d0 (refactor a bit) +}; +======= +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::get_trait_def_id; +use clippy_utils::higher::VecArgs; +use clippy_utils::macros::root_macro_call_first_node; +use clippy_utils::source::snippet_opt; +use clippy_utils::ty::implements_trait; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_ast::{LitIntType, LitKind, UintTy}; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, LangItem, QPath}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use std::fmt::{self, Display, Formatter}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for `Vec` or array initializations that contain only one range. + /// + /// ### Why is this bad? +<<<<<<< HEAD +<<<<<<< HEAD + /// This is almost always incorrect, as it will result in a `Vec` that has only one element. + /// Almost always, the programmer intended for it to include all elements in the range or for + /// the end of the range to be the length instead. +======= + /// This is almost always incorrect, as it will result in a `Vec` that has only element. Almost + /// always, the programmer intended for it to include all elements in the range or for the end + /// of the range to be the length instead. +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= + /// This is almost always incorrect, as it will result in a `Vec` that has only one element. + /// Almost always, the programmer intended for it to include all elements in the range or for + /// the end of the range to be the length instead. +>>>>>>> 830d307d0 (refactor a bit) + /// + /// ### Example + /// ```rust + /// let x = [0..200]; + /// ``` + /// Use instead: + /// ```rust + /// // If it was intended to include every element in the range... + /// let x = (0..200).collect::>(); + /// // ...Or if 200 was meant to be the len + /// let x = [0; 200]; + /// ``` + #[clippy::version = "1.72.0"] + pub SINGLE_RANGE_IN_VEC_INIT, + suspicious, + "checks for initialization of `Vec` or arrays which consist of a single range" +} +declare_lint_pass!(SingleRangeInVecInit => [SINGLE_RANGE_IN_VEC_INIT]); + +enum SuggestedType { + Vec, + Array, +} + +impl SuggestedType { + fn starts_with(&self) -> &'static str { + if matches!(self, SuggestedType::Vec) { + "vec!" + } else { + "[" + } + } + + fn ends_with(&self) -> &'static str { + if matches!(self, SuggestedType::Vec) { "" } else { "]" } + } +} + +impl Display for SuggestedType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + if matches!(&self, SuggestedType::Vec) { + write!(f, "a `Vec`") + } else { + write!(f, "an array") + } + } +} + +impl LateLintPass<'_> for SingleRangeInVecInit { + fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { + // inner_expr: `vec![0..200]` or `[0..200]` + // ^^^^^^ ^^^^^^^ + // span: `vec![0..200]` or `[0..200]` + // ^^^^^^^^^^^^ ^^^^^^^^ +<<<<<<< HEAD +<<<<<<< HEAD + // suggested_type: What to print, "an array" or "a `Vec`" + let (inner_expr, span, suggested_type) = if let ExprKind::Array([inner_expr]) = expr.kind +======= + // kind: What to print, an array or a `Vec` + let (inner_expr, span, kind) = if let ExprKind::Array([inner_expr]) = expr.kind +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= + // suggested_type: What to print, "an array" or "a `Vec`" + let (inner_expr, span, suggested_type) = if let ExprKind::Array([inner_expr]) = expr.kind +>>>>>>> 830d307d0 (refactor a bit) + && !expr.span.from_expansion() + { + (inner_expr, expr.span, SuggestedType::Array) + } else if let Some(macro_call) = root_macro_call_first_node(cx, expr) + && let Some(VecArgs::Vec([expr])) = VecArgs::hir(cx, expr) + { + (expr, macro_call.span, SuggestedType::Vec) + } else { + return; + }; + + let ExprKind::Struct(QPath::LangItem(lang_item, ..), [start, end], None) = inner_expr.kind else { + return; + }; + + if matches!(lang_item, LangItem::Range) + && let ty = cx.typeck_results().expr_ty(start.expr) + && let Some(snippet) = snippet_opt(cx, span) + // `is_from_proc_macro` will skip any `vec![]`. Let's not! +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 830d307d0 (refactor a bit) + && snippet.starts_with(suggested_type.starts_with()) + && snippet.ends_with(suggested_type.ends_with()) + && let Some(start_snippet) = snippet_opt(cx, start.span) + && let Some(end_snippet) = snippet_opt(cx, end.span) +<<<<<<< HEAD + { +======= + && snippet.starts_with(kind.starts_with()) + && snippet.ends_with(kind.ends_with()) + { + let mut app = Applicability::MaybeIncorrect; + let start_snippet = snippet_with_applicability(cx, start.span, "...", &mut app); + let end_snippet = snippet_with_applicability(cx, end.span, "...", &mut app); + +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= + { +>>>>>>> 830d307d0 (refactor a bit) + let should_emit_every_value = if let Some(step_def_id) = get_trait_def_id(cx, &["core", "iter", "Step"]) + && implements_trait(cx, ty, step_def_id, &[]) + { + true + } else { + false + }; + let should_emit_of_len = if let Some(copy_def_id) = cx.tcx.lang_items().copy_trait() + && implements_trait(cx, ty, copy_def_id, &[]) + && let ExprKind::Lit(lit_kind) = end.expr.kind + && let LitKind::Int(.., suffix_type) = lit_kind.node + && let LitIntType::Unsigned(UintTy::Usize) | LitIntType::Unsuffixed = suffix_type + { + true + } else { + false + }; + + if should_emit_every_value || should_emit_of_len { + span_lint_and_then( + cx, + SINGLE_RANGE_IN_VEC_INIT, + span, +<<<<<<< HEAD +<<<<<<< HEAD + &format!("{suggested_type} of `Range` that is only one element"), +======= + &format!("{kind} of `Range` that is only one element"), +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= + &format!("{suggested_type} of `Range` that is only one element"), +>>>>>>> 830d307d0 (refactor a bit) + |diag| { + if should_emit_every_value { + diag.span_suggestion( + span, +<<<<<<< HEAD +<<<<<<< HEAD + "if you wanted a `Vec` that contains the entire range, try", + format!("({start_snippet}..{end_snippet}).collect::>()"), + Applicability::MaybeIncorrect, +======= + "if you wanted a `Vec` that contains every value in the range, try", + format!("({start_snippet}..{end_snippet}).collect::>()"), + app, +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= + "if you wanted a `Vec` that contains the entire range, try", + format!("({start_snippet}..{end_snippet}).collect::>()"), + Applicability::MaybeIncorrect, +>>>>>>> 830d307d0 (refactor a bit) + ); + } + + if should_emit_of_len { + diag.span_suggestion( + inner_expr.span, +<<<<<<< HEAD +<<<<<<< HEAD + format!("if you wanted {suggested_type} of len {end_snippet}, try"), + format!("{start_snippet}; {end_snippet}"), + Applicability::MaybeIncorrect, +======= + format!("if you wanted {kind} of len {end_snippet}, try"), + format!("{start_snippet}; {end_snippet}"), + app, +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= + format!("if you wanted {suggested_type} of len {end_snippet}, try"), + format!("{start_snippet}; {end_snippet}"), + Applicability::MaybeIncorrect, +>>>>>>> 830d307d0 (refactor a bit) + ); + } + }, + ); + } + } + } +} diff --git a/clippy_lints/src/size_of_in_element_count.rs b/clippy_lints/src/size_of_in_element_count.rs index ac4e29e9dfdf..a91dd21269c5 100644 --- a/clippy_lints/src/size_of_in_element_count.rs +++ b/clippy_lints/src/size_of_in_element_count.rs @@ -4,8 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::{match_def_path, paths}; use if_chain::if_chain; -use rustc_hir::BinOpKind; -use rustc_hir::{Expr, ExprKind}; +use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, Ty, TypeAndMut}; use rustc_session::{declare_lint_pass, declare_tool_lint}; diff --git a/clippy_lints/src/size_of_ref.rs b/clippy_lints/src/size_of_ref.rs index 8abec06c641c..89ac8cd8ca97 100644 --- a/clippy_lints/src/size_of_ref.rs +++ b/clippy_lints/src/size_of_ref.rs @@ -1,4 +1,6 @@ -use clippy_utils::{diagnostics::span_lint_and_help, path_def_id, ty::peel_mid_ty_refs}; +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::path_def_id; +use clippy_utils::ty::peel_mid_ty_refs; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index a2109038a057..858135c8d464 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -74,7 +74,7 @@ enum InitializationType<'tcx> { impl<'tcx> LateLintPass<'tcx> for SlowVectorInit { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - // Matches initialization on reassignements. For example: `vec = Vec::with_capacity(100)` + // Matches initialization on reassignments. For example: `vec = Vec::with_capacity(100)` if_chain! { if let ExprKind::Assign(left, right, _) = expr.kind; diff --git a/clippy_lints/src/std_instead_of_core.rs b/clippy_lints/src/std_instead_of_core.rs index a13bc7a51887..f239165276ff 100644 --- a/clippy_lints/src/std_instead_of_core.rs +++ b/clippy_lints/src/std_instead_of_core.rs @@ -1,9 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_help; +use rustc_hir::def::Res; use rustc_hir::def_id::DefId; -use rustc_hir::{def::Res, HirId, Path, PathSegment}; +use rustc_hir::{HirId, Path, PathSegment}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{sym, symbol::kw, Span}; +use rustc_span::symbol::kw; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index b2f4b310915a..58724852b3c4 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -1,8 +1,10 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg}; use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::ty::is_type_lang_item; -use clippy_utils::{get_expr_use_or_unification_node, peel_blocks, SpanlessEq}; -use clippy_utils::{get_parent_expr, is_lint_allowed, match_function_call, method_calls, paths}; +use clippy_utils::{ + get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, is_path_diagnostic_item, method_calls, + peel_blocks, SpanlessEq, +}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; @@ -132,7 +134,7 @@ declare_clippy_lint! { /// Probably lots of false positives. If an index comes from a known valid position (e.g. /// obtained via `char_indices` over the same string), it is totally OK. /// - /// # Example + /// ### Example /// ```rust,should_panic /// &"Ölkanne"[1..]; /// ``` @@ -255,7 +257,8 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { if_chain! { // Find std::str::converts::from_utf8 - if let Some(args) = match_function_call(cx, e, &paths::STR_FROM_UTF8); + if let ExprKind::Call(fun, args) = e.kind; + if is_path_diagnostic_item(cx, fun, sym::str_from_utf8); // Find string::as_bytes if let ExprKind::AddrOf(BorrowKind::Ref, _, args) = args[0].kind; @@ -292,6 +295,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { } if_chain! { + if !in_external_macro(cx.sess(), e.span); if let ExprKind::MethodCall(path, receiver, ..) = &e.kind; if path.ident.name == sym!(as_bytes); if let ExprKind::Lit(lit) = &receiver.kind; diff --git a/clippy_lints/src/strlen_on_c_strings.rs b/clippy_lints/src/strlen_on_c_strings.rs index 03324c66e8ef..b3db5e9a4221 100644 --- a/clippy_lints/src/strlen_on_c_strings.rs +++ b/clippy_lints/src/strlen_on_c_strings.rs @@ -1,11 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_context; -use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item}; use clippy_utils::visitors::is_expr_unsafe; use clippy_utils::{get_parent_node, match_libc_symbol}; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, Node, UnsafeSource}; +use rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, LangItem, Node, UnsafeSource}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; @@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings { let val_name = snippet_with_context(cx, self_arg.span, ctxt, "..", &mut app).0; let method_name = if is_type_diagnostic_item(cx, ty, sym::cstring_type) { "as_bytes" - } else if is_type_diagnostic_item(cx, ty, sym::CStr) { + } else if is_type_lang_item(cx, ty, LangItem::CStr) { "to_bytes" } else { return; @@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings { STRLEN_ON_C_STRINGS, span, "using `libc::strlen` on a `CString` or `CStr` value", - "try this", + "try", format!("{val_name}.{method_name}().len()"), app, ); diff --git a/clippy_lints/src/suspicious_doc_comments.rs b/clippy_lints/src/suspicious_doc_comments.rs index e5746ca99cac..8be4ec3dc64c 100644 --- a/clippy_lints/src/suspicious_doc_comments.rs +++ b/clippy_lints/src/suspicious_doc_comments.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and_then}; use if_chain::if_chain; -use rustc_ast::{token::CommentKind, AttrKind, AttrStyle, Attribute, Item}; +use rustc_ast::token::CommentKind; +use rustc_ast::{AttrKind, AttrStyle, Attribute, Item}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; diff --git a/clippy_lints/src/suspicious_operation_groupings.rs b/clippy_lints/src/suspicious_operation_groupings.rs index fab8e9c2ec1c..e2cdc48b583c 100644 --- a/clippy_lints/src/suspicious_operation_groupings.rs +++ b/clippy_lints/src/suspicious_operation_groupings.rs @@ -577,7 +577,7 @@ fn ident_difference_expr_with_base_location( | (AssignOp(_, _, _), AssignOp(_, _, _)) | (Assign(_, _, _), Assign(_, _, _)) | (TryBlock(_), TryBlock(_)) - | (Await(_), Await(_)) + | (Await(_, _), Await(_, _)) | (Async(_, _), Async(_, _)) | (Block(_, _), Block(_, _)) | (Closure(_), Closure(_)) diff --git a/clippy_lints/src/suspicious_xor_used_as_pow.rs b/clippy_lints/src/suspicious_xor_used_as_pow.rs index 9c0dc8096d0d..6fa49afe0ecd 100644 --- a/clippy_lints/src/suspicious_xor_used_as_pow.rs +++ b/clippy_lints/src/suspicious_xor_used_as_pow.rs @@ -1,4 +1,5 @@ -use clippy_utils::{numeric_literal::NumericLiteral, source::snippet_with_context}; +use clippy_utils::numeric_literal::NumericLiteral; +use clippy_utils::source::snippet_with_context; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index f7eef03d1d47..98158ed0aee8 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -11,8 +11,8 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Spanned; -use rustc_span::SyntaxContext; -use rustc_span::{sym, symbol::Ident, Span}; +use rustc_span::symbol::Ident; +use rustc_span::{sym, Span, SyntaxContext}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/tests_outside_test_module.rs b/clippy_lints/src/tests_outside_test_module.rs index 0a0a77082e02..b356666d852a 100644 --- a/clippy_lints/src/tests_outside_test_module.rs +++ b/clippy_lints/src/tests_outside_test_module.rs @@ -1,8 +1,11 @@ -use clippy_utils::{diagnostics::span_lint_and_note, is_in_cfg_test, is_in_test_function}; -use rustc_hir::{intravisit::FnKind, Body, FnDecl}; +use clippy_utils::diagnostics::span_lint_and_note; +use clippy_utils::{is_in_cfg_test, is_in_test_function}; +use rustc_hir::intravisit::FnKind; +use rustc_hir::{Body, FnDecl}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::{def_id::LocalDefId, Span}; +use rustc_span::def_id::LocalDefId; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/to_digit_is_some.rs b/clippy_lints/src/to_digit_is_some.rs index 2512500a6be7..f1b703fde0e6 100644 --- a/clippy_lints/src/to_digit_is_some.rs +++ b/clippy_lints/src/to_digit_is_some.rs @@ -82,7 +82,7 @@ impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome { TO_DIGIT_IS_SOME, expr.span, "use of `.to_digit(..).is_some()`", - "try this", + "try", if is_method_call { format!("{char_arg_snip}.is_digit({radix_snip})") } else { diff --git a/clippy_lints/src/trailing_empty_array.rs b/clippy_lints/src/trailing_empty_array.rs index 1382c1a40da2..bb9da3a20470 100644 --- a/clippy_lints/src/trailing_empty_array.rs +++ b/clippy_lints/src/trailing_empty_array.rs @@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray { None, &format!( "consider annotating `{}` with `#[repr(C)]` or another `repr` attribute", - cx.tcx.def_path_str(item.owner_id.to_def_id()) + cx.tcx.def_path_str(item.owner_id) ), ); } @@ -60,7 +60,7 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'_>, item: &Item<'_ if let Some(last_field) = data.fields().last(); if let rustc_hir::TyKind::Array(_, rustc_hir::ArrayLen::Body(length)) = last_field.ty.kind; - // Then check if that that array zero-sized + // Then check if that array is zero-sized let length = Const::from_anon_const(cx.tcx, length.def_id); let length = length.try_eval_target_usize(cx.tcx, cx.param_env); if let Some(length) = length; diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index b5f11b4acae0..44c0007d5341 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability}; -use clippy_utils::{SpanlessEq, SpanlessHash}; +use clippy_utils::{is_from_proc_macro, SpanlessEq, SpanlessHash}; use core::hash::{Hash, Hasher}; use if_chain::if_chain; use itertools::Itertools; @@ -9,7 +10,7 @@ use rustc_data_structures::unhash::UnhashMap; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::{ - GenericArg, GenericBound, Generics, Item, ItemKind, Node, Path, PathSegment, PredicateOrigin, QPath, + GenericArg, GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment, PredicateOrigin, QPath, TraitBoundModifier, TraitItem, TraitRef, Ty, TyKind, WherePredicate, }; use rustc_lint::{LateContext, LateLintPass}; @@ -37,12 +38,12 @@ declare_clippy_lint! { #[clippy::version = "1.38.0"] pub TYPE_REPETITION_IN_BOUNDS, nursery, - "types are repeated unnecessary in trait bounds use `+` instead of using `T: _, T: _`" + "types are repeated unnecessarily in trait bounds, use `+` instead of using `T: _, T: _`" } declare_clippy_lint! { /// ### What it does - /// Checks for cases where generics are being used and multiple + /// Checks for cases where generics or trait objects are being used and multiple /// syntax specifications for trait bounds are used simultaneously. /// /// ### Why is this bad? @@ -86,15 +87,16 @@ declare_clippy_lint! { "check if the same trait bounds are specified more than once during a generic declaration" } -#[derive(Copy, Clone)] +#[derive(Clone)] pub struct TraitBounds { max_trait_bounds: u64, + msrv: Msrv, } impl TraitBounds { #[must_use] - pub fn new(max_trait_bounds: u64) -> Self { - Self { max_trait_bounds } + pub fn new(max_trait_bounds: u64, msrv: Msrv) -> Self { + Self { max_trait_bounds, msrv } } } @@ -139,7 +141,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { ) = cx.tcx.hir().get_if_local(*def_id); then { if self_bounds_map.is_empty() { - for bound in self_bounds.iter() { + for bound in *self_bounds { let Some((self_res, self_segments, _)) = get_trait_info_from_bound(bound) else { continue }; self_bounds_map.insert(self_res, self_segments); } @@ -167,10 +169,232 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { } } } + + fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 122793b49 (Update trait_bounds.rs) + if_chain! { + if let TyKind::Ref(.., mut_ty) = &ty.kind; + if let TyKind::TraitObject(bounds, ..) = mut_ty.ty.kind; + if bounds.len() > 2; + then { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> b169bdb73 (Comments) + + // Build up a hash of every trait we've seen + // When we see a trait for the first time, add it to unique_traits + // so we can later use it to build a string of all traits exactly once, without duplicates + +<<<<<<< HEAD + let mut seen_def_ids = FxHashSet::default(); + let mut unique_traits = Vec::new(); + + // Iterate the bounds and add them to our seen hash + // If we haven't yet seen it, add it to the fixed traits +<<<<<<< HEAD +<<<<<<< HEAD +======= + let mut bounds_span = bounds[0].span; + + for bound in bounds.iter().skip(1) { + bounds_span = bounds_span.to(bound.span); + } + + let mut seen_def_ids = FxHashSet::default(); + let mut fixed_traits = Vec::new(); + +>>>>>>> 122793b49 (Update trait_bounds.rs) +======= +======= +>>>>>>> b169bdb73 (Comments) + let mut seen_def_ids = FxHashSet::default(); + let mut unique_traits = Vec::new(); + + // Iterate the bounds and add them to our seen hash + // If we haven't yet seen it, add it to the fixed traits +>>>>>>> 5c8a00923 (Comments) + for bound in bounds.iter() { +======= + for bound in bounds { +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= + for bound in bounds { +======= + for bound in bounds.iter() { +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + let Some(def_id) = bound.trait_ref.trait_def_id() else { continue; }; + + let new_trait = seen_def_ids.insert(def_id); + + if new_trait { +<<<<<<< HEAD +<<<<<<< HEAD + unique_traits.push(bound); + } + } + + // If the number of unique traits isn't the same as the number of traits in the bounds, + // there must be 1 or more duplicates + if bounds.len() != unique_traits.len() { + let mut bounds_span = bounds[0].span; + + for bound in bounds.iter().skip(1) { + bounds_span = bounds_span.to(bound.span); + } + + let fixed_trait_snippet = unique_traits +======= + fixed_traits.push(bound); +======= + unique_traits.push(bound); +>>>>>>> b169bdb73 (Comments) + } + } + + // If the number of unique traits isn't the same as the number of traits in the bounds, + // there must be 1 or more duplicates + if bounds.len() != unique_traits.len() { + let mut bounds_span = bounds[0].span; + + for bound in bounds.iter().skip(1) { + bounds_span = bounds_span.to(bound.span); + } + +<<<<<<< HEAD + let fixed_trait_snippet = fixed_traits +>>>>>>> 122793b49 (Update trait_bounds.rs) +======= + let fixed_trait_snippet = unique_traits +>>>>>>> b169bdb73 (Comments) + .iter() + .filter_map(|b| snippet_opt(cx, b.span)) + .collect::>() + .join(" + "); + + span_lint_and_sugg( + cx, + TRAIT_DUPLICATION_IN_BOUNDS, + bounds_span, + "this trait bound is already specified in trait declaration", + "try", + fixed_trait_snippet, + Applicability::MaybeIncorrect, + ); + } +<<<<<<< HEAD +======= + let TyKind::Ref( + .., + MutTy { + ty: Ty { + kind: TyKind::TraitObject( + bounds, + .. + ), + .. + }, + .. + } + ) = ty.kind else { return; }; + + if bounds.len() < 2 { + return; + } + + let mut bounds_span = bounds[0].span; + + for bound in bounds.iter().skip(1) { + bounds_span = bounds_span.to(bound.span); + } + + let mut seen_def_ids = FxHashSet::default(); + let mut fixed_traits = Vec::new(); + + for bound in bounds.iter() { + let Some(def_id) = bound.trait_ref.trait_def_id() else { continue; }; + + let new_trait = seen_def_ids.insert(def_id); + +<<<<<<< HEAD + if already_seen { + span_lint_and_sugg( + cx, + TRAIT_DUPLICATION_IN_BOUNDS, + bounds_span, + "this trait bound is already specified in trait declaration", + "consider removing this trait bound", + traits.clone(), + Applicability::MaybeIncorrect, + ); +>>>>>>> 478555d46 (wip) +======= + if new_trait { + fixed_traits.push(bound); +>>>>>>> b9788fef2 (Working) + } + } + + if bounds.len() != fixed_traits.len() { + let fixed_trait_snippet = fixed_traits + .iter() + .filter_map(|b| snippet_opt(cx, b.span)) + .collect::>() + .join(" + "); + + span_lint_and_sugg( + cx, + TRAIT_DUPLICATION_IN_BOUNDS, + bounds_span, + "this trait bound is already specified in trait declaration", + "try", + fixed_trait_snippet, + Applicability::MaybeIncorrect, + ); +======= + } +>>>>>>> 122793b49 (Update trait_bounds.rs) + } + } +<<<<<<< HEAD + + extract_msrv_attr!(LateContext); +======= +>>>>>>> e4f5d83fa (Fixed formatting.) } impl TraitBounds { - fn check_type_repetition<'tcx>(self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) { + /// Is the given bound a `?Sized` bound, and is combining it (i.e. `T: X + ?Sized`) an error on +<<<<<<< HEAD +<<<<<<< HEAD + /// this MSRV? See for details. + fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool { + if !self.msrv.meets(msrvs::MAYBE_BOUND_IN_WHERE) +<<<<<<< HEAD +======= + /// this MSRV? See https://github.com/rust-lang/rust-clippy/issues/8772 for details. +======= + /// this MSRV? See for details. +>>>>>>> 765a6e4a9 (put issue link between <>) + fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool { + if !self.msrv.meets(msrvs::COMBINED_MAYBE_BOUND) +>>>>>>> 87c28b946 ([`type_repetition_in_bounds`]: respect msrv for combining maybe bounds) +======= +>>>>>>> 33b6d0d20 (rename MSRV alias, add MSRV to lint doc) + && let GenericBound::Trait(tr, TraitBoundModifier::Maybe) = bound + { + cx.tcx.lang_items().get(LangItem::Sized) == tr.trait_ref.path.res.opt_def_id() + } else { + false + } + } + + fn check_type_repetition<'tcx>(&self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) { struct SpanlessTy<'cx, 'tcx> { ty: &'tcx Ty<'tcx>, cx: &'cx LateContext<'tcx>, @@ -201,11 +425,31 @@ impl TraitBounds { if p.origin != PredicateOrigin::ImplTrait; if p.bounds.len() as u64 <= self.max_trait_bounds; if !p.span.from_expansion(); +<<<<<<< HEAD +<<<<<<< HEAD + let bounds = p.bounds.iter().filter(|b| !self.cannot_combine_maybe_bound(cx, b)).collect::>(); + if !bounds.is_empty(); + if let Some(ref v) = map.insert(SpanlessTy { ty: p.bounded_ty, cx }, bounds); + if !is_from_proc_macro(cx, p.bounded_ty); +======= if let Some(ref v) = map.insert( SpanlessTy { ty: p.bounded_ty, cx }, p.bounds.iter().collect::>() ); +<<<<<<< HEAD + let bounded_ty = snippet(cx, p.bounded_ty.span, "_"); + if let TyKind::Path(qpath) = p.bounded_ty.kind; + if format!("{}:", rustc_hir_pretty::qpath_to_string(&qpath)) == format!("{bounded_ty}:"); +>>>>>>> 6ea7cd8ec (Fix #10504, don't lint on derived code) +======= +======= + let bounds = p.bounds.iter().filter(|b| !self.cannot_combine_maybe_bound(cx, b)).collect::>(); + if !bounds.is_empty(); + if let Some(ref v) = map.insert(SpanlessTy { ty: p.bounded_ty, cx }, bounds); +>>>>>>> 87c28b946 ([`type_repetition_in_bounds`]: respect msrv for combining maybe bounds) + if !is_from_proc_macro(cx, p.bounded_ty); +>>>>>>> a434a7715 (`impl WithSearchPat for Ty`) then { let trait_bounds = v .iter() @@ -287,7 +531,7 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) { "this trait bound is already specified in the where clause", None, "consider removing this trait bound", - ); + ); } } } diff --git a/clippy_lints/src/transmute/transmute_int_to_non_zero.rs b/clippy_lints/src/transmute/transmute_int_to_non_zero.rs index 5503653253c5..c0d0d2b93dc0 100644 --- a/clippy_lints/src/transmute/transmute_int_to_non_zero.rs +++ b/clippy_lints/src/transmute/transmute_int_to_non_zero.rs @@ -4,10 +4,8 @@ use clippy_utils::sugg; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::{ - query::Key, - ty::{self, Ty}, -}; +use rustc_middle::query::Key; +use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::sym; /// Checks for `transmute_int_to_non_zero` lint. diff --git a/clippy_lints/src/transmute/transmute_null_to_fn.rs b/clippy_lints/src/transmute/transmute_null_to_fn.rs index e75d7f6bf1d5..4944381da24d 100644 --- a/clippy_lints/src/transmute/transmute_null_to_fn.rs +++ b/clippy_lints/src/transmute/transmute_null_to_fn.rs @@ -31,9 +31,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t match arg.kind { // Catching: // transmute over constants that resolve to `null`. - ExprKind::Path(ref _qpath) - if matches!(constant(cx, cx.typeck_results(), arg), Some((Constant::RawPtr(0), _))) => - { + ExprKind::Path(ref _qpath) if matches!(constant(cx, cx.typeck_results(), arg), Some(Constant::RawPtr(0))) => { lint_expr(cx, expr); true }, diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs index 31a9b69ca158..857d2ad82588 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs @@ -24,7 +24,7 @@ pub(super) fn check<'tcx>( "transmute from a pointer to a pointer", |diag| { if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) { - let sugg = arg.as_ty(cx.tcx.mk_ptr(*to_ty)); + let sugg = arg.as_ty(Ty::new_ptr(cx.tcx,*to_ty)); diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified); } }, diff --git a/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/clippy_lints/src/transmute/transmute_ref_to_ref.rs index 426c7253806e..ea9ad99618ab 100644 --- a/clippy_lints/src/transmute/transmute_ref_to_ref.rs +++ b/clippy_lints/src/transmute/transmute_ref_to_ref.rs @@ -64,8 +64,8 @@ pub(super) fn check<'tcx>( }; let ty_to_and_mut = ty::TypeAndMut { ty: *ty_to, mutbl: *to_mutbl }; let sugg_paren = arg - .as_ty(cx.tcx.mk_ptr(ty_from_and_mut)) - .as_ty(cx.tcx.mk_ptr(ty_to_and_mut)); + .as_ty(Ty::new_ptr(cx.tcx,ty_from_and_mut)) + .as_ty(Ty::new_ptr(cx.tcx,ty_to_and_mut)); let sugg = if *to_mutbl == Mutability::Mut { sugg_paren.mut_addr_deref() } else { diff --git a/clippy_lints/src/transmute/transmute_undefined_repr.rs b/clippy_lints/src/transmute/transmute_undefined_repr.rs index 5e24213d07fd..13b7eeb43a6f 100644 --- a/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -3,8 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::ty::is_c_void; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty::SubstsRef; -use rustc_middle::ty::{self, IntTy, Ty, TypeAndMut, UintTy}; +use rustc_middle::ty::{self, IntTy, SubstsRef, Ty, TypeAndMut, UintTy}; #[expect(clippy::too_many_lines)] pub(super) fn check<'tcx>( diff --git a/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs index 85cd74f23ef7..513a913f56ad 100644 --- a/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs +++ b/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs @@ -6,7 +6,8 @@ use rustc_ast::ExprPrecedence; use rustc_errors::Applicability; use rustc_hir::{Expr, Node}; use rustc_lint::LateContext; -use rustc_middle::ty::{cast::CastKind, Ty}; +use rustc_middle::ty::cast::CastKind; +use rustc_middle::ty::Ty; /// Checks for `transmutes_expressible_as_ptr_casts` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/clippy_lints/src/transmute/transmuting_null.rs b/clippy_lints/src/transmute/transmuting_null.rs index 1e407fc4138c..770914e99e16 100644 --- a/clippy_lints/src/transmute/transmuting_null.rs +++ b/clippy_lints/src/transmute/transmuting_null.rs @@ -1,4 +1,4 @@ -use clippy_utils::consts::{constant_context, Constant}; +use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint; use clippy_utils::{is_integer_literal, is_path_diagnostic_item}; use rustc_hir::{Expr, ExprKind}; @@ -16,9 +16,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t } // Catching transmute over constants that resolve to `null`. - let mut const_eval_context = constant_context(cx, cx.typeck_results()); if let ExprKind::Path(ref _qpath) = arg.kind && - let Some(Constant::RawPtr(0)) = const_eval_context.expr(arg) + let Some(Constant::RawPtr(0)) = constant(cx, cx.typeck_results(), arg) { span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG); return true; diff --git a/clippy_lints/src/transmute/useless_transmute.rs b/clippy_lints/src/transmute/useless_transmute.rs index 56207fe767c5..b6615410e257 100644 --- a/clippy_lints/src/transmute/useless_transmute.rs +++ b/clippy_lints/src/transmute/useless_transmute.rs @@ -43,7 +43,7 @@ pub(super) fn check<'tcx>( let sugg = if *ptr_ty == rty_and_mut { arg.as_ty(to_ty) } else { - arg.as_ty(cx.tcx.mk_ptr(rty_and_mut)).as_ty(to_ty) + arg.as_ty(Ty::new_ptr(cx.tcx,rty_and_mut)).as_ty(to_ty) }; diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified); diff --git a/clippy_lints/src/transmute/utils.rs b/clippy_lints/src/transmute/utils.rs index 62efd13b8d90..1cf6cf8548a6 100644 --- a/clippy_lints/src/transmute/utils.rs +++ b/clippy_lints/src/transmute/utils.rs @@ -2,7 +2,8 @@ use rustc_hir as hir; use rustc_hir::Expr; use rustc_hir_typeck::{cast, FnCtxt, Inherited}; use rustc_lint::LateContext; -use rustc_middle::ty::{cast::CastKind, Ty}; +use rustc_middle::ty::cast::CastKind; +use rustc_middle::ty::Ty; use rustc_span::DUMMY_SP; // check if the component types of the transmuted collection and the result have different ABI, diff --git a/clippy_lints/src/tuple_array_conversions.rs b/clippy_lints/src/tuple_array_conversions.rs new file mode 100644 index 000000000000..a14fb249eb2d --- /dev/null +++ b/clippy_lints/src/tuple_array_conversions.rs @@ -0,0 +1,484 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> b1acbde61 (Add msrv check and make test pass) +use clippy_utils::{ + diagnostics::span_lint_and_help, + is_from_proc_macro, + msrvs::{self, Msrv}, + path_to_local, +}; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::{is_from_proc_macro, path_to_local}; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_ast::LitKind; +use rustc_hir::{Expr, ExprKind, HirId, Node, Pat}; +======= +use itertools::Itertools; +use rustc_ast::LitKind; +use rustc_hir::{Expr, ExprKind, Node, Pat}; +>>>>>>> 95b24d44a (Fix FP) +======= +use rustc_ast::LitKind; +use rustc_hir::{Expr, ExprKind, HirId, Node, Pat}; +>>>>>>> 826edd75e (heavily refactor) +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_middle::ty; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use std::iter::once; + +declare_clippy_lint! { + /// ### What it does + /// Checks for tuple<=>array conversions that are not done with `.into()`. + /// + /// ### Why is this bad? +<<<<<<< HEAD + /// It's unnecessary complexity. `.into()` works for tuples<=>arrays at or below 12 elements and + /// conveys the intent a lot better, while also leaving less room for hard to spot bugs! +<<<<<<< HEAD +======= +use clippy_utils::{diagnostics::span_lint_and_help, is_from_proc_macro, path_to_local}; +use rustc_hir::*; +======= +use itertools::Itertools; +use rustc_hir::{Expr, ExprKind, Node, Pat}; +>>>>>>> b1acbde61 (Add msrv check and make test pass) +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::{lint::in_external_macro, ty}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use std::iter::once; + +declare_clippy_lint! { + /// ### What it does + /// Checks for tuple<=>array conversions that are not done with `.into()`. + /// + /// ### Why is this bad? +<<<<<<< HEAD +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + /// It's overly complex. `.into()` works for tuples<=>arrays with less than 13 elements and + /// conveys the intent a lot better, while also leaving less room for bugs! +>>>>>>> b1acbde61 (Add msrv check and make test pass) +======= +>>>>>>> 826edd75e (heavily refactor) +======= + /// It may be unnecessary complexity. `.into()` works for converting tuples + /// <=> arrays of up to 12 elements and may convey intent more clearly. +>>>>>>> 4102a309d ([`tuple_array_conversions`]: move from `complexity` to `nursery`) + /// + /// ### Example + /// ```rust,ignore + /// let t1 = &[(1, 2), (3, 4)]; + /// let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect(); + /// ``` + /// Use instead: + /// ```rust,ignore + /// let t1 = &[(1, 2), (3, 4)]; + /// let v1: Vec<[u32; 2]> = t1.iter().map(|&t| t.into()).collect(); + /// ``` + #[clippy::version = "1.72.0"] + pub TUPLE_ARRAY_CONVERSIONS, +<<<<<<< HEAD + complexity, +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> b1acbde61 (Add msrv check and make test pass) +======= + pedantic, +>>>>>>> 4102a309d ([`tuple_array_conversions`]: move from `complexity` to `nursery`) + "checks for tuple<=>array conversions that are not done with `.into()`" +} +impl_lint_pass!(TupleArrayConversions => [TUPLE_ARRAY_CONVERSIONS]); + +#[derive(Clone)] +pub struct TupleArrayConversions { + pub msrv: Msrv, +<<<<<<< HEAD +} + +impl LateLintPass<'_> for TupleArrayConversions { + fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { + if !in_external_macro(cx.sess(), expr.span) && self.msrv.meets(msrvs::TUPLE_ARRAY_CONVERSIONS) { + match expr.kind { + ExprKind::Array(elements) if (1..=12).contains(&elements.len()) => check_array(cx, expr, elements), + ExprKind::Tup(elements) if (1..=12).contains(&elements.len()) => check_tuple(cx, expr, elements), + _ => {}, + } + } + } + + extract_msrv_attr!(LateContext); +} + +#[expect( + clippy::blocks_in_if_conditions, + reason = "not a FP, but this is much easier to understand" +)] +fn check_array<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &'tcx [Expr<'tcx>]) { + if should_lint( + cx, + elements, + // This is cursed. + Some, + |(first_id, local)| { + if let Node::Pat(pat) = local + && let parent = parent_pat(cx, pat) + && parent.hir_id == first_id + { + return matches!( + cx.typeck_results().pat_ty(parent).peel_refs().kind(), + ty::Tuple(len) if len.len() == elements.len() + ); + } + + false + }, + ) || should_lint( + cx, + elements, + |(i, expr)| { + if let ExprKind::Field(path, field) = expr.kind && field.as_str() == i.to_string() { + return Some((i, path)); + }; + + None + }, + |(first_id, local)| { + if let Node::Pat(pat) = local + && let parent = parent_pat(cx, pat) + && parent.hir_id == first_id + { + return matches!( + cx.typeck_results().pat_ty(parent).peel_refs().kind(), + ty::Tuple(len) if len.len() == elements.len() + ); + } + + false + }, + ) { + emit_lint(cx, expr, ToType::Array); + } +} + +#[expect( + clippy::blocks_in_if_conditions, + reason = "not a FP, but this is much easier to understand" +)] +#[expect(clippy::cast_possible_truncation)] +fn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &'tcx [Expr<'tcx>]) { + if should_lint(cx, elements, Some, |(first_id, local)| { + if let Node::Pat(pat) = local + && let parent = parent_pat(cx, pat) + && parent.hir_id == first_id + { + return matches!( + cx.typeck_results().pat_ty(parent).peel_refs().kind(), + ty::Array(_, len) if len.eval_target_usize(cx.tcx, cx.param_env) as usize == elements.len() + ); + } + + false + }) || should_lint( + cx, + elements, + |(i, expr)| { + if let ExprKind::Index(path, index) = expr.kind + && let ExprKind::Lit(lit) = index.kind + && let LitKind::Int(val, _) = lit.node + && val as usize == i + { + return Some((i, path)); + }; + + None + }, + |(first_id, local)| { + if let Node::Pat(pat) = local + && let parent = parent_pat(cx, pat) + && parent.hir_id == first_id + { + return matches!( + cx.typeck_results().pat_ty(parent).peel_refs().kind(), + ty::Array(_, len) if len.eval_target_usize(cx.tcx, cx.param_env) as usize == elements.len() + ); + } + + false + }, + ) { + emit_lint(cx, expr, ToType::Tuple); + } +} + +/// Walks up the `Pat` until it's reached the final containing `Pat`. +fn parent_pat<'tcx>(cx: &LateContext<'tcx>, start: &'tcx Pat<'tcx>) -> &'tcx Pat<'tcx> { +======= + "default lint description" +======= +>>>>>>> b1acbde61 (Add msrv check and make test pass) +} + +impl LateLintPass<'_> for TupleArrayConversions { + fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { + if !in_external_macro(cx.sess(), expr.span) && self.msrv.meets(msrvs::TUPLE_ARRAY_CONVERSIONS) { + match expr.kind { + ExprKind::Array(elements) if (1..=12).contains(&elements.len()) => check_array(cx, expr, elements), + ExprKind::Tup(elements) if (1..=12).contains(&elements.len()) => check_tuple(cx, expr, elements), + _ => {}, + } + } + } + + extract_msrv_attr!(LateContext); +} + +#[expect( + clippy::blocks_in_if_conditions, + reason = "not a FP, but this is much easier to understand" +)] +fn check_array<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &'tcx [Expr<'tcx>]) { + if should_lint( + cx, + elements, + // This is cursed. + Some, + |(first_id, local)| { + if let Node::Pat(pat) = local + && let parent = parent_pat(cx, pat) + && parent.hir_id == first_id + { + return matches!( + cx.typeck_results().pat_ty(parent).peel_refs().kind(), + ty::Tuple(len) if len.len() == elements.len() + ); + } + + false + }, + ) || should_lint( + cx, + elements, + |(i, expr)| { + if let ExprKind::Field(path, field) = expr.kind && field.as_str() == i.to_string() { + return Some((i, path)); + }; + + None + }, + |(first_id, local)| { + if let Node::Pat(pat) = local + && let parent = parent_pat(cx, pat) + && parent.hir_id == first_id + { + return matches!( + cx.typeck_results().pat_ty(parent).peel_refs().kind(), + ty::Tuple(len) if len.len() == elements.len() + ); + } + + false + }, + ) { + emit_lint(cx, expr, ToType::Array); + } +} + +#[expect( + clippy::blocks_in_if_conditions, + reason = "not a FP, but this is much easier to understand" +)] +#[expect(clippy::cast_possible_truncation)] +fn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &'tcx [Expr<'tcx>]) { + if should_lint(cx, elements, Some, |(first_id, local)| { + if let Node::Pat(pat) = local + && let parent = parent_pat(cx, pat) + && parent.hir_id == first_id + { + return matches!( + cx.typeck_results().pat_ty(parent).peel_refs().kind(), + ty::Array(_, len) if len.eval_target_usize(cx.tcx, cx.param_env) as usize == elements.len() + ); + } + + false + }) || should_lint( + cx, + elements, + |(i, expr)| { + if let ExprKind::Index(path, index) = expr.kind + && let ExprKind::Lit(lit) = index.kind + && let LitKind::Int(val, _) = lit.node + && val as usize == i + { + return Some((i, path)); + }; + + None + }, + |(first_id, local)| { + if let Node::Pat(pat) = local + && let parent = parent_pat(cx, pat) + && parent.hir_id == first_id + { + return matches!( + cx.typeck_results().pat_ty(parent).peel_refs().kind(), + ty::Array(_, len) if len.eval_target_usize(cx.tcx, cx.param_env) as usize == elements.len() + ); + } + + false + }, + ) { + emit_lint(cx, expr, ToType::Tuple); + } +} + +/// Walks up the `Pat` until it's reached the final containing `Pat`. +<<<<<<< HEAD +fn backtrack_pat<'tcx>(cx: &LateContext<'tcx>, start: &'tcx Pat<'tcx>) -> &'tcx Pat<'tcx> { +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= +fn parent_pat<'tcx>(cx: &LateContext<'tcx>, start: &'tcx Pat<'tcx>) -> &'tcx Pat<'tcx> { +>>>>>>> b1acbde61 (Add msrv check and make test pass) + let mut end = start; + for (_, node) in cx.tcx.hir().parent_iter(start.hir_id) { + if let Node::Pat(pat) = node { + end = pat; + } else { + break; + } + } + end +} + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +fn path_to_locals<'tcx>( + cx: &LateContext<'tcx>, + exprs: impl IntoIterator>, +) -> Option>> { +======= +fn path_to_locals<'tcx>(cx: &LateContext<'tcx>, exprs: &[&'tcx Expr<'tcx>]) -> Option>> { +>>>>>>> b1acbde61 (Add msrv check and make test pass) + exprs + .iter() + .map(|element| path_to_local(element).and_then(|local| cx.tcx.hir().find(local))) + .collect() +} + +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= +>>>>>>> 826edd75e (heavily refactor) +#[derive(Clone, Copy)] +enum ToType { + Array, + Tuple, +} + +impl ToType { +<<<<<<< HEAD +<<<<<<< HEAD + fn msg(self) -> &'static str { +======= + fn help(self) -> &'static str { +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + fn msg(self) -> &'static str { +>>>>>>> b1acbde61 (Add msrv check and make test pass) + match self { + ToType::Array => "it looks like you're trying to convert a tuple to an array", + ToType::Tuple => "it looks like you're trying to convert an array to a tuple", + } + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> b1acbde61 (Add msrv check and make test pass) + + fn help(self) -> &'static str { + match self { + ToType::Array => "use `.into()` instead, or `<[T; N]>::from` if type annotations are needed", + ToType::Tuple => "use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed", + } + } +<<<<<<< HEAD +======= +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= +>>>>>>> b1acbde61 (Add msrv check and make test pass) +} + +fn emit_lint<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, to_type: ToType) -> bool { + if !is_from_proc_macro(cx, expr) { + span_lint_and_help( + cx, + TUPLE_ARRAY_CONVERSIONS, + expr.span, +<<<<<<< HEAD +<<<<<<< HEAD + to_type.msg(), + None, + to_type.help(), +======= + to_type.help(), + None, + "use `.into()` instead", +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + to_type.msg(), + None, + to_type.help(), +>>>>>>> b1acbde61 (Add msrv check and make test pass) + ); + + return true; + } + + false +} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 826edd75e (heavily refactor) + +fn should_lint<'tcx>( + cx: &LateContext<'tcx>, + elements: &'tcx [Expr<'tcx>], + map: impl FnMut((usize, &'tcx Expr<'tcx>)) -> Option<(usize, &Expr<'_>)>, + predicate: impl FnMut((HirId, &Node<'tcx>)) -> bool, +) -> bool { + if let Some(elements) = elements + .iter() + .enumerate() + .map(map) + .collect::>>() + && let Some(locals) = elements + .iter() + .map(|(_, element)| path_to_local(element).and_then(|local| cx.tcx.hir().find(local))) + .collect::>>() + && let [first, rest @ ..] = &*locals + && let Node::Pat(first_pat) = first + && let parent = parent_pat(cx, first_pat).hir_id + && rest.iter().chain(once(first)).map(|i| (parent, i)).all(predicate) + { + return true; + } + + false +} +<<<<<<< HEAD +======= +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= +>>>>>>> 826edd75e (heavily refactor) diff --git a/clippy_lints/src/types/borrowed_box.rs b/clippy_lints/src/types/borrowed_box.rs index acdf54710691..306ca5724da1 100644 --- a/clippy_lints/src/types/borrowed_box.rs +++ b/clippy_lints/src/types/borrowed_box.rs @@ -2,8 +2,9 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{self as hir, GenericArg, GenericBounds, GenericParamKind}; -use rustc_hir::{HirId, Lifetime, MutTy, Mutability, Node, QPath, TyKind}; +use rustc_hir::{ + self as hir, GenericArg, GenericBounds, GenericParamKind, HirId, Lifetime, MutTy, Mutability, Node, QPath, TyKind, +}; use rustc_lint::LateContext; use rustc_span::sym; diff --git a/clippy_lints/src/types/box_collection.rs b/clippy_lints/src/types/box_collection.rs index 43665a922d44..4a5a94f26302 100644 --- a/clippy_lints/src/types/box_collection.rs +++ b/clippy_lints/src/types/box_collection.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::{path_def_id, qpath_generic_tys}; -use rustc_hir::{self as hir, def_id::DefId, QPath}; +use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, QPath}; use rustc_lint::LateContext; use rustc_span::{sym, Symbol}; diff --git a/clippy_lints/src/types/linked_list.rs b/clippy_lints/src/types/linked_list.rs index 5fb708741e58..fba804bbe088 100644 --- a/clippy_lints/src/types/linked_list.rs +++ b/clippy_lints/src/types/linked_list.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_help; -use rustc_hir::{self as hir, def_id::DefId}; +use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir}; use rustc_lint::LateContext; use rustc_span::symbol::sym; diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index c6834a8fdaa2..3c873a5901d4 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -90,8 +90,8 @@ declare_clippy_lint! { /// /// ### Why is this bad? /// `Option<_>` represents an optional value. `Option>` - /// represents an optional optional value which is logically the same thing as an optional - /// value but has an unneeded extra level of wrapping. + /// represents an optional value which itself wraps an optional. This is logically the + /// same thing as an optional value but has an unneeded extra level of wrapping. /// /// If you have a case where `Some(Some(_))`, `Some(None)` and `None` are distinct cases, /// consider a custom `enum` instead, with clear names for each case. diff --git a/clippy_lints/src/types/option_option.rs b/clippy_lints/src/types/option_option.rs index 8767e3c30a68..60622903af1d 100644 --- a/clippy_lints/src/types/option_option.rs +++ b/clippy_lints/src/types/option_option.rs @@ -1,7 +1,8 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::{path_def_id, qpath_generic_tys}; use if_chain::if_chain; -use rustc_hir::{self as hir, def_id::DefId, QPath}; +use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, QPath}; use rustc_lint::LateContext; use rustc_span::symbol::sym; diff --git a/clippy_lints/src/types/rc_buffer.rs b/clippy_lints/src/types/rc_buffer.rs index 855137b14d84..8239630ac2d8 100644 --- a/clippy_lints/src/types/rc_buffer.rs +++ b/clippy_lints/src/types/rc_buffer.rs @@ -2,7 +2,8 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{path_def_id, qpath_generic_tys}; use rustc_errors::Applicability; -use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind}; +use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, QPath, TyKind}; use rustc_lint::LateContext; use rustc_span::symbol::sym; diff --git a/clippy_lints/src/types/rc_mutex.rs b/clippy_lints/src/types/rc_mutex.rs index a75972cf3ddb..a616c3e4ea83 100644 --- a/clippy_lints/src/types/rc_mutex.rs +++ b/clippy_lints/src/types/rc_mutex.rs @@ -1,7 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::{path_def_id, qpath_generic_tys}; use if_chain::if_chain; -use rustc_hir::{self as hir, def_id::DefId, QPath}; +use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, QPath}; use rustc_lint::LateContext; use rustc_span::symbol::sym; diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs index f7adc9d35558..d369c6df9199 100644 --- a/clippy_lints/src/types/redundant_allocation.rs +++ b/clippy_lints/src/types/redundant_allocation.rs @@ -2,7 +2,8 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::{path_def_id, qpath_generic_tys}; use rustc_errors::Applicability; -use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind}; +use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, QPath, TyKind}; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::LateContext; use rustc_middle::ty::TypeVisitableExt; diff --git a/clippy_lints/src/types/vec_box.rs b/clippy_lints/src/types/vec_box.rs index d3062f3d2e36..decc183ad961 100644 --- a/clippy_lints/src/types/vec_box.rs +++ b/clippy_lints/src/types/vec_box.rs @@ -3,7 +3,8 @@ use clippy_utils::last_path_segment; use clippy_utils::source::snippet; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{self as hir, def_id::DefId, GenericArg, QPath, TyKind}; +use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, GenericArg, QPath, TyKind}; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::LateContext; use rustc_middle::ty::layout::LayoutOf; diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index 2920684ade33..701a42db0e57 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -11,7 +11,7 @@ use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource}; use rustc_lexer::{tokenize, TokenKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{BytePos, Pos, Span, SyntaxContext}; declare_clippy_lint! { @@ -92,7 +92,39 @@ declare_clippy_lint! { "annotating safe code with a safety comment" } -declare_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS, UNNECESSARY_SAFETY_COMMENT]); +#[derive(Copy, Clone)] +pub struct UndocumentedUnsafeBlocks { + accept_comment_above_statement: bool, +<<<<<<< HEAD +<<<<<<< HEAD + accept_comment_above_attributes: bool, +} + +impl UndocumentedUnsafeBlocks { + pub fn new(accept_comment_above_statement: bool, accept_comment_above_attributes: bool) -> Self { + Self { + accept_comment_above_statement, + accept_comment_above_attributes, +======= +======= + accept_comment_above_attributes: bool, +>>>>>>> cc2e49f69 (allow safety comment above attributes) +} + +impl UndocumentedUnsafeBlocks { + pub fn new(accept_comment_above_statement: bool, accept_comment_above_attributes: bool) -> Self { + Self { + accept_comment_above_statement, +<<<<<<< HEAD +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= + accept_comment_above_attributes, +>>>>>>> cc2e49f69 (allow safety comment above attributes) + } + } +} + +impl_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS, UNNECESSARY_SAFETY_COMMENT]); impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) { @@ -101,7 +133,22 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id) && !is_unsafe_from_proc_macro(cx, block.span) && !block_has_safety_comment(cx, block.span) - && !block_parents_have_safety_comment(cx, block.hir_id) +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) + && !block_parents_have_safety_comment( + self.accept_comment_above_statement, + self.accept_comment_above_attributes, + cx, + block.hir_id, + ) +<<<<<<< HEAD +======= + && !block_parents_have_safety_comment(self.accept_comment_above_statement, cx, block.hir_id) +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) { let source_map = cx.tcx.sess.source_map(); let span = if source_map.is_multiline(block.span) { @@ -313,29 +360,133 @@ fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool { // Checks if any parent {expression, statement, block, local, const, static} // has a safety comment -fn block_parents_have_safety_comment(cx: &LateContext<'_>, id: hir::HirId) -> bool { +fn block_parents_have_safety_comment( + accept_comment_above_statement: bool, +<<<<<<< HEAD +<<<<<<< HEAD + accept_comment_above_attributes: bool, +======= +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= + accept_comment_above_attributes: bool, +>>>>>>> cc2e49f69 (allow safety comment above attributes) + cx: &LateContext<'_>, + id: hir::HirId, +) -> bool { if let Some(node) = get_parent_node(cx.tcx, id) { return match node { - Node::Expr(expr) => !is_branchy(expr) && span_in_body_has_safety_comment(cx, expr.span), + Node::Expr(expr) => { + if let Some( + Node::Local(hir::Local { span, .. }) + | Node::Item(hir::Item { + kind: hir::ItemKind::Const(..) | ItemKind::Static(..), + span, + .. + }), + ) = get_parent_node(cx.tcx, expr.hir_id) + { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) + let hir_id = match get_parent_node(cx.tcx, expr.hir_id) { + Some(Node::Local(hir::Local { hir_id, .. })) => *hir_id, + Some(Node::Item(hir::Item { owner_id, .. })) => { + cx.tcx.hir().local_def_id_to_hir_id(owner_id.def_id) + }, + _ => unreachable!(), + }; + +<<<<<<< HEAD + // if unsafe block is part of a let/const/static statement, + // and accept_comment_above_statement is set to true + // we accept the safety comment in the line the precedes this statement. + accept_comment_above_statement + && span_with_attrs_in_body_has_safety_comment( + cx, + *span, + hir_id, + accept_comment_above_attributes, + ) + } else { + !is_branchy(expr) + && span_with_attrs_in_body_has_safety_comment( + cx, + expr.span, + expr.hir_id, + accept_comment_above_attributes, + ) +======= +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) + // if unsafe block is part of a let/const/static statement, + // and accept_comment_above_statement is set to true + // we accept the safety comment in the line the precedes this statement. + accept_comment_above_statement + && span_with_attrs_in_body_has_safety_comment( + cx, + *span, + hir_id, + accept_comment_above_attributes, + ) + } else { +<<<<<<< HEAD + !is_branchy(expr) && span_in_body_has_safety_comment(cx, expr.span) +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= + !is_branchy(expr) + && span_with_attrs_in_body_has_safety_comment( + cx, + expr.span, + expr.hir_id, + accept_comment_above_attributes, + ) +>>>>>>> cc2e49f69 (allow safety comment above attributes) + } + }, Node::Stmt(hir::Stmt { kind: - hir::StmtKind::Local(hir::Local { span, .. }) - | hir::StmtKind::Expr(hir::Expr { span, .. }) - | hir::StmtKind::Semi(hir::Expr { span, .. }), + hir::StmtKind::Local(hir::Local { span, hir_id, .. }) + | hir::StmtKind::Expr(hir::Expr { span, hir_id, .. }) + | hir::StmtKind::Semi(hir::Expr { span, hir_id, .. }), .. }) - | Node::Local(hir::Local { span, .. }) - | Node::Item(hir::Item { + | Node::Local(hir::Local { span, hir_id, .. }) => { + span_with_attrs_in_body_has_safety_comment(cx, *span, *hir_id, accept_comment_above_attributes) + }, + Node::Item(hir::Item { kind: hir::ItemKind::Const(..) | ItemKind::Static(..), span, + owner_id, .. - }) => span_in_body_has_safety_comment(cx, *span), + }) => span_with_attrs_in_body_has_safety_comment( + cx, + *span, + cx.tcx.hir().local_def_id_to_hir_id(owner_id.def_id), + accept_comment_above_attributes, + ), _ => false, }; } false } +/// Extends `span` to also include its attributes, then checks if that span has a safety comment. +fn span_with_attrs_in_body_has_safety_comment( + cx: &LateContext<'_>, + span: Span, + hir_id: HirId, + accept_comment_above_attributes: bool, +) -> bool { + let span = if accept_comment_above_attributes { + include_attrs_in_span(cx, hir_id, span) + } else { + span + }; + + span_in_body_has_safety_comment(cx, span) +} + /// Checks if an expression is "branchy", e.g. loop, match/if/etc. fn is_branchy(expr: &hir::Expr<'_>) -> bool { matches!( @@ -360,6 +511,15 @@ fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool { ) || span_in_body_has_safety_comment(cx, span) } +fn include_attrs_in_span(cx: &LateContext<'_>, hir_id: HirId, span: Span) -> Span { + span.to(cx + .tcx + .hir() + .attrs(hir_id) + .iter() + .fold(span, |acc, attr| acc.to(attr.span))) +} + enum HasSafetyComment { Yes(BytePos), No, @@ -546,7 +706,14 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option { for (_, node) in map.parent_iter(body.hir_id) { match node { Node::Expr(e) => span = e.span, - Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::Local(_) => (), + Node::Block(_) + | Node::Arm(_) + | Node::Stmt(_) + | Node::Local(_) + | Node::Item(hir::Item { + kind: hir::ItemKind::Const(..) | ItemKind::Static(..), + .. + }) => (), _ => break, } } diff --git a/clippy_lints/src/unit_return_expecting_ord.rs b/clippy_lints/src/unit_return_expecting_ord.rs index 289ca4e9bed3..99a1d197678b 100644 --- a/clippy_lints/src/unit_return_expecting_ord.rs +++ b/clippy_lints/src/unit_return_expecting_ord.rs @@ -4,7 +4,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::{Closure, Expr, ExprKind, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; -use rustc_middle::ty::{Clause, GenericPredicates, PredicateKind, ProjectionPredicate, TraitPredicate}; +use rustc_middle::ty::{ClauseKind, GenericPredicates, ProjectionPredicate, TraitPredicate}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{sym, BytePos, Span}; @@ -45,7 +45,7 @@ fn get_trait_predicates_for_trait_id<'tcx>( let mut preds = Vec::new(); for (pred, _) in generics.predicates { if_chain! { - if let PredicateKind::Clause(Clause::Trait(poly_trait_pred)) = pred.kind().skip_binder(); + if let ClauseKind::Trait(poly_trait_pred) = pred.kind().skip_binder(); let trait_pred = cx.tcx.erase_late_bound_regions(pred.kind().rebind(poly_trait_pred)); if let Some(trait_def_id) = trait_id; if trait_def_id == trait_pred.trait_ref.def_id; @@ -63,7 +63,7 @@ fn get_projection_pred<'tcx>( trait_pred: TraitPredicate<'tcx>, ) -> Option> { generics.predicates.iter().find_map(|(proj_pred, _)| { - if let ty::PredicateKind::Clause(Clause::Projection(pred)) = proj_pred.kind().skip_binder() { + if let ClauseKind::Projection(pred) = proj_pred.kind().skip_binder() { let projection_pred = cx.tcx.erase_late_bound_regions(proj_pred.kind().rebind(pred)); if projection_pred.projection_ty.substs == trait_pred.trait_ref.substs { return Some(projection_pred); diff --git a/clippy_lints/src/unnamed_address.rs b/clippy_lints/src/unnamed_address.rs index 0bcafde658a4..0f5cdb6aaea1 100644 --- a/clippy_lints/src/unnamed_address.rs +++ b/clippy_lints/src/unnamed_address.rs @@ -96,9 +96,7 @@ impl LateLintPass<'_> for UnnamedAddress { if let ExprKind::Call(func, [ref _left, ref _right]) = expr.kind; if let ExprKind::Path(ref func_qpath) = func.kind; if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id(); - if match_def_path(cx, def_id, &paths::PTR_EQ) || - match_def_path(cx, def_id, &paths::RC_PTR_EQ) || - match_def_path(cx, def_id, &paths::ARC_PTR_EQ); + if match_def_path(cx, def_id, &paths::PTR_EQ); let ty_param = cx.typeck_results().node_substs(func.hir_id).type_at(0); if ty_param.is_trait(); then { diff --git a/clippy_lints/src/unnecessary_box_returns.rs b/clippy_lints/src/unnecessary_box_returns.rs index 912bcda630b8..ba0638ced8c9 100644 --- a/clippy_lints/src/unnecessary_box_returns.rs +++ b/clippy_lints/src/unnecessary_box_returns.rs @@ -1,6 +1,32 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::{diagnostics::span_lint_and_then, ty::approx_ty_size}; +======= use clippy_utils::diagnostics::span_lint_and_then; +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +use clippy_utils::{diagnostics::span_lint_and_then, ty::approx_ty_size}; +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +use clippy_utils::{diagnostics::span_lint_and_then, ty::approx_ty_size}; +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) +======= +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::ty::approx_ty_size; +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::ty::approx_ty_size; +======= +use clippy_utils::{diagnostics::span_lint_and_then, ty::approx_ty_size}; +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) use rustc_errors::Applicability; -use rustc_hir::{def_id::LocalDefId, FnDecl, FnRetTy, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind}; +use rustc_hir::def_id::LocalDefId; +use rustc_hir::{FnDecl, FnRetTy, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Symbol; @@ -10,6 +36,24 @@ declare_clippy_lint! { /// /// Checks for a return type containing a `Box` where `T` implements `Sized` /// +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + /// The lint ignores `Box` where `T` is larger than `unnecessary_box_size`, + /// as returning a large `T` directly may be detrimental to performance. + /// +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + /// The lint ignores `Box` where `T` is larger than `unnecessary_box_size`, + /// as returning a large `T` directly may be detrimental to performance. + /// +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + /// The lint ignores `Box` where `T` is larger than `unnecessary_box_size`, + /// as returning a large `T` directly may be detrimental to performance. + /// +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) /// ### Why is this bad? /// /// It's better to just return `T` in these cases. The caller may not need @@ -36,14 +80,47 @@ declare_clippy_lint! { pub struct UnnecessaryBoxReturns { avoid_breaking_exported_api: bool, +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + maximum_size: u64, +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + maximum_size: u64, +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + maximum_size: u64, +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) } impl_lint_pass!(UnnecessaryBoxReturns => [UNNECESSARY_BOX_RETURNS]); impl UnnecessaryBoxReturns { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + pub fn new(avoid_breaking_exported_api: bool, maximum_size: u64) -> Self { + Self { + avoid_breaking_exported_api, + maximum_size, +======= pub fn new(avoid_breaking_exported_api: bool) -> Self { Self { avoid_breaking_exported_api, +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + pub fn new(avoid_breaking_exported_api: bool, maximum_size: u64) -> Self { + Self { + avoid_breaking_exported_api, + maximum_size, +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + pub fn new(avoid_breaking_exported_api: bool, maximum_size: u64) -> Self { + Self { + avoid_breaking_exported_api, + maximum_size, +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) } } @@ -71,8 +148,27 @@ impl UnnecessaryBoxReturns { let boxed_ty = return_ty.boxed_ty(); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) + // It's sometimes useful to return Box if T is unsized, so don't lint those. + // Also, don't lint if we know that T is very large, in which case returning + // a Box may be beneficial. + if boxed_ty.is_sized(cx.tcx, cx.param_env) && approx_ty_size(cx, boxed_ty) <= self.maximum_size { +<<<<<<< HEAD +<<<<<<< HEAD +======= // it's sometimes useful to return Box if T is unsized, so don't lint those if boxed_ty.is_sized(cx.tcx, cx.param_env) { +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) span_lint_and_then( cx, UNNECESSARY_BOX_RETURNS, @@ -102,7 +198,15 @@ impl LateLintPass<'_> for UnnecessaryBoxReturns { fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) { // Ignore implementations of traits, because the lint should be on the +<<<<<<< HEAD +<<<<<<< HEAD + // trait, not on the implementation of it. +======= // trait, not on the implmentation of it. +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + // trait, not on the implementation of it. +>>>>>>> d2061faf9 (Spelling) let Node::Item(parent) = cx.tcx.hir().get_parent(item.hir_id()) else { return }; let ItemKind::Impl(parent) = parent.kind else { return }; if parent.of_trait.is_some() { diff --git a/clippy_lints/src/unnecessary_owned_empty_strings.rs b/clippy_lints/src/unnecessary_owned_empty_strings.rs index 6e802794f5aa..57a4a429e129 100644 --- a/clippy_lints/src/unnecessary_owned_empty_strings.rs +++ b/clippy_lints/src/unnecessary_owned_empty_strings.rs @@ -1,4 +1,5 @@ -use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::ty::is_type_lang_item; use clippy_utils::{match_def_path, paths}; use if_chain::if_chain; use rustc_ast::ast::LitKind; diff --git a/clippy_lints/src/unnecessary_struct_initialization.rs b/clippy_lints/src/unnecessary_struct_initialization.rs index 084b031982d8..f4111186c642 100644 --- a/clippy_lints/src/unnecessary_struct_initialization.rs +++ b/clippy_lints/src/unnecessary_struct_initialization.rs @@ -1,4 +1,7 @@ -use clippy_utils::{diagnostics::span_lint_and_sugg, get_parent_expr, path_to_local, source::snippet, ty::is_copy}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet; +use clippy_utils::ty::is_copy; +use clippy_utils::{get_parent_expr, path_to_local}; use rustc_hir::{BindingAnnotation, Expr, ExprKind, Node, PatKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; diff --git a/clippy_lints/src/unnecessary_wraps.rs b/clippy_lints/src/unnecessary_wraps.rs index 8b0e0ce5a300..f34f8d0e3538 100644 --- a/clippy_lints/src/unnecessary_wraps.rs +++ b/clippy_lints/src/unnecessary_wraps.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; -use clippy_utils::{contains_return, is_res_lang_ctor, path_res, return_ty, visitors::find_all_ret_expressions}; +use clippy_utils::visitors::find_all_ret_expressions; +use clippy_utils::{contains_return, is_res_lang_ctor, path_res, return_ty}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; @@ -163,7 +164,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps { span_lint_and_then(cx, UNNECESSARY_WRAPS, span, lint_msg.as_str(), |diag| { diag.span_suggestion( fn_decl.output.span(), - return_type_sugg_msg.as_str(), + return_type_sugg_msg, return_type_sugg, Applicability::MaybeIncorrect, ); diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index a57bf7ee8225..c1cc7471d537 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -6,7 +6,8 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::over; use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; -use rustc_ast::{self as ast, Mutability, Pat, PatKind, PatKind::*, DUMMY_NODE_ID}; +use rustc_ast::PatKind::*; +use rustc_ast::{self as ast, Mutability, Pat, PatKind, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; diff --git a/clippy_lints/src/unused_async.rs b/clippy_lints/src/unused_async.rs index 55651a28be92..64f233c50c25 100644 --- a/clippy_lints/src/unused_async.rs +++ b/clippy_lints/src/unused_async.rs @@ -1,5 +1,17 @@ -use clippy_utils::diagnostics::span_lint_and_help; -use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor}; +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::is_def_id_trait_method; +<<<<<<< HEAD +======= +use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then}; +>>>>>>> 1e73a9eb4 (do not consider `await` in nested `async` blocks) +======= +use clippy_utils::diagnostics::span_lint_and_then; +>>>>>>> 3eeeaa2bc (remove old span_lint) +======= +>>>>>>> b713cd594 (move `is_in_trait_method` to utils and rename) +use rustc_hir::intravisit::{walk_body, walk_expr, walk_fn, FnKind, Visitor}; use rustc_hir::{Body, Expr, ExprKind, FnDecl, YieldSource}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; @@ -42,6 +54,18 @@ declare_lint_pass!(UnusedAsync => [UNUSED_ASYNC]); struct AsyncFnVisitor<'a, 'tcx> { cx: &'a LateContext<'tcx>, found_await: bool, + /// Also keep track of `await`s in nested async blocks so we can mention + /// it in a note +<<<<<<< HEAD +<<<<<<< HEAD + await_in_async_block: Option, +======= + found_await_in_async_block: bool, +>>>>>>> 1e73a9eb4 (do not consider `await` in nested `async` blocks) +======= + await_in_async_block: Option, +>>>>>>> 8ef6240af (point to `await` expr in note) + async_depth: usize, } impl<'a, 'tcx> Visitor<'tcx> for AsyncFnVisitor<'a, 'tcx> { @@ -49,7 +73,21 @@ impl<'a, 'tcx> Visitor<'tcx> for AsyncFnVisitor<'a, 'tcx> { fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) { if let ExprKind::Yield(_, YieldSource::Await { .. }) = ex.kind { - self.found_await = true; + if self.async_depth == 1 { + self.found_await = true; +<<<<<<< HEAD +<<<<<<< HEAD + } else if self.await_in_async_block.is_none() { + self.await_in_async_block = Some(ex.span); +======= + } else { + self.found_await_in_async_block = true; +>>>>>>> 1e73a9eb4 (do not consider `await` in nested `async` blocks) +======= + } else if self.await_in_async_block.is_none() { + self.await_in_async_block = Some(ex.span); +>>>>>>> 8ef6240af (point to `await` expr in note) + } } walk_expr(self, ex); } @@ -57,6 +95,20 @@ impl<'a, 'tcx> Visitor<'tcx> for AsyncFnVisitor<'a, 'tcx> { fn nested_visit_map(&mut self) -> Self::Map { self.cx.tcx.hir() } + + fn visit_body(&mut self, b: &'tcx Body<'tcx>) { + let is_async_block = matches!(b.generator_kind, Some(rustc_hir::GeneratorKind::Async(_))); + + if is_async_block { + self.async_depth += 1; + } + + walk_body(self, b); + + if is_async_block { + self.async_depth -= 1; + } + } } impl<'tcx> LateLintPass<'tcx> for UnusedAsync { @@ -69,18 +121,75 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync { span: Span, def_id: LocalDefId, ) { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if !span.from_expansion() && fn_kind.asyncness().is_async() && !is_def_id_trait_method(cx, def_id) { +======= if !span.from_expansion() && fn_kind.asyncness().is_async() { - let mut visitor = AsyncFnVisitor { cx, found_await: false }; +>>>>>>> 1e73a9eb4 (do not consider `await` in nested `async` blocks) +======= + if !span.from_expansion() && fn_kind.asyncness().is_async() && !is_in_trait_impl(cx, def_id) { +>>>>>>> a43bfefd1 ([`unused_async`]: don't lint on async trait impls) +======= + if !span.from_expansion() && fn_kind.asyncness().is_async() && !is_def_id_trait_method(cx, def_id) { +>>>>>>> b713cd594 (move `is_in_trait_method` to utils and rename) + let mut visitor = AsyncFnVisitor { + cx, + found_await: false, + async_depth: 0, +<<<<<<< HEAD +<<<<<<< HEAD + await_in_async_block: None, +======= + found_await_in_async_block: false, +>>>>>>> 1e73a9eb4 (do not consider `await` in nested `async` blocks) +======= + await_in_async_block: None, +>>>>>>> 8ef6240af (point to `await` expr in note) + }; walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), def_id); if !visitor.found_await { + span_lint_and_then( +<<<<<<< HEAD +======= + cx, + UNUSED_ASYNC, + span, + "unused `async` for function with no await statements", + |diag| { + diag.help("consider removing the `async` from this function"); + + if let Some(span) = visitor.await_in_async_block { + diag.span_note( + span, + "`await` used in an async block, which does not require \ + the enclosing function to be `async`", + ); + } + }, + ); +<<<<<<< HEAD span_lint_and_help( +>>>>>>> 1e73a9eb4 (do not consider `await` in nested `async` blocks) cx, UNUSED_ASYNC, span, "unused `async` for function with no await statements", - None, - "consider removing the `async` from this function", + |diag| { + diag.help("consider removing the `async` from this function"); + + if let Some(span) = visitor.await_in_async_block { + diag.span_note( + span, + "`await` used in an async block, which does not require \ + the enclosing function to be `async`", + ); + } + }, ); +======= +>>>>>>> 3eeeaa2bc (remove old span_lint) } } } diff --git a/clippy_lints/src/unused_unit.rs b/clippy_lints/src/unused_unit.rs index cad8da18c2fb..95e74718d806 100644 --- a/clippy_lints/src/unused_unit.rs +++ b/clippy_lints/src/unused_unit.rs @@ -1,7 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::{position_before_rarrow, snippet_opt}; use if_chain::if_chain; -use rustc_ast::{ast, visit::FnKind, ClosureBinder}; +use rustc_ast::visit::FnKind; +use rustc_ast::{ast, ClosureBinder}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index 377d3fb6f4e1..c99b0290c0c0 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; -use clippy_utils::higher; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::{path_to_local, usage::is_potentially_mutated}; +use clippy_utils::usage::is_potentially_mutated; +use clippy_utils::{higher, path_to_local}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor}; diff --git a/clippy_lints/src/upper_case_acronyms.rs b/clippy_lints/src/upper_case_acronyms.rs index 1d2d3eb12e11..4df1e3299ed9 100644 --- a/clippy_lints/src/upper_case_acronyms.rs +++ b/clippy_lints/src/upper_case_acronyms.rs @@ -65,7 +65,7 @@ fn correct_ident(ident: &str) -> String { let mut ident = fragments.clone().next().unwrap(); for (ref prev, ref curr) in fragments.tuple_windows() { - if [prev, curr] + if <[&String; 2]>::from((prev, curr)) .iter() .all(|s| s.len() == 1 && s.chars().next().unwrap().is_ascii_uppercase()) { diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index 5a02987453c4..fcf77e8eab9a 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -5,13 +5,12 @@ use clippy_utils::ty::same_type_and_consts; use if_chain::if_chain; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; +use rustc_hir::def::{CtorOf, DefKind, Res}; +use rustc_hir::def_id::LocalDefId; +use rustc_hir::intravisit::{walk_inf, walk_ty, Visitor}; use rustc_hir::{ - self as hir, - def::{CtorOf, DefKind, Res}, - def_id::LocalDefId, - intravisit::{walk_inf, walk_ty, Visitor}, - Expr, ExprKind, FnRetTy, FnSig, GenericArg, GenericArgsParentheses, GenericParam, GenericParamKind, HirId, Impl, - ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind, + self as hir, Expr, ExprKind, FnRetTy, FnSig, GenericArg, GenericArgsParentheses, GenericParam, GenericParamKind, + HirId, Impl, ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind, }; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::{LateContext, LateLintPass}; diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index ddbe6b2c7904..48b5038e5069 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -1,15 +1,22 @@ +<<<<<<< HEAD +use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_context}; +======= use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; +use clippy_utils::is_ty_alias; use clippy_utils::source::{snippet, snippet_with_context}; +>>>>>>> e4f5d83fa (Fixed formatting.) use clippy_utils::sugg::Sugg; use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts}; -use clippy_utils::{get_parent_expr, is_trait_method, match_def_path, path_to_local, paths}; +use clippy_utils::{get_parent_expr, is_trait_method, is_ty_alias, match_def_path, path_to_local, paths}; use if_chain::if_chain; use rustc_errors::Applicability; +use rustc_hir::def_id::DefId; use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, MatchSource, Node, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::sym; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does @@ -42,6 +49,87 @@ pub struct UselessConversion { impl_lint_pass!(UselessConversion => [USELESS_CONVERSION]); +enum MethodOrFunction { + Method, + Function, +} + +impl MethodOrFunction { + /// Maps the argument position in `pos` to the parameter position. + /// For methods, `self` is skipped. + fn param_pos(self, pos: usize) -> usize { + match self { + MethodOrFunction::Method => pos + 1, + MethodOrFunction::Function => pos, + } + } +} + +/// Returns the span of the `IntoIterator` trait bound in the function pointed to by `fn_did` +fn into_iter_bound(cx: &LateContext<'_>, fn_did: DefId, into_iter_did: DefId, param_index: u32) -> Option { + cx.tcx + .predicates_of(fn_did) + .predicates + .iter() + .find_map(|&(ref pred, span)| { +<<<<<<< HEAD + if let ty::ClauseKind::Trait(tr) = pred.kind().skip_binder() +======= + if let ty::PredicateKind::Clause(ty::Clause::Trait(tr)) = pred.kind().skip_binder() +>>>>>>> de1f41001 (merge `explicit_into_iter_fn_arg` into `useless_conversion`) + && tr.def_id() == into_iter_did + && tr.self_ty().is_param(param_index) + { + Some(span) + } else { + None + } + }) +} + +/// Extracts the receiver of a `.into_iter()` method call. +fn into_iter_call<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>) -> Option<&'hir Expr<'hir>> { + if let ExprKind::MethodCall(name, recv, _, _) = expr.kind + && is_trait_method(cx, expr, sym::IntoIterator) + && name.ident.name == sym::into_iter + { + Some(recv) + } else { + None + } +} + +/// Same as [`into_iter_call`], but tries to look for the innermost `.into_iter()` call, e.g.: +/// `foo.into_iter().into_iter()` +/// ^^^ we want this expression +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5a7e33e5b (add plural form to useless_conversion if depth > 0) +fn into_iter_deep_call<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) -> (&'hir Expr<'hir>, usize) { + let mut depth = 0; + while let Some(recv) = into_iter_call(cx, expr) { + expr = recv; + depth += 1; +<<<<<<< HEAD + } + (expr, depth) +======= +fn into_iter_deep_call<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) -> Option<&'hir Expr<'hir>> { + loop { + if let Some(recv) = into_iter_call(cx, expr) { + expr = recv; + } else { + return Some(expr); + } + } +>>>>>>> de1f41001 (merge `explicit_into_iter_fn_arg` into `useless_conversion`) +======= + } + (expr, depth) +>>>>>>> 5a7e33e5b (add plural form to useless_conversion if depth > 0) +} + #[expect(clippy::too_many_lines)] impl<'tcx> LateLintPass<'tcx> for UselessConversion { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { @@ -81,9 +169,86 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { ); } } - if is_trait_method(cx, e, sym::IntoIterator) && name.ident.name == sym::into_iter { - if get_parent_expr(cx, e).is_some() && - let Some(id) = path_to_local(recv) && + if let Some(into_iter_recv) = into_iter_call(cx, e) + // Make sure that there is no parent expression, or if there is, make sure it's not a `.into_iter()` call. + // The reason for that is that we only want to lint once (the outermost call) + // in cases like `foo.into_iter().into_iter()` + && get_parent_expr(cx, e) + .and_then(|parent| into_iter_call(cx, parent)) + .is_none() + { + if let Some(parent) = get_parent_expr(cx, e) { + let parent_fn = match parent.kind { + ExprKind::Call(recv, args) if let ExprKind::Path(ref qpath) = recv.kind => { + cx.qpath_res(qpath, recv.hir_id).opt_def_id() + .map(|did| (did, args, MethodOrFunction::Function)) + } + ExprKind::MethodCall(.., args, _) => { + cx.typeck_results().type_dependent_def_id(parent.hir_id) + .map(|did| (did, args, MethodOrFunction::Method)) + } + _ => None, + }; + + if let Some((parent_fn_did, args, kind)) = parent_fn + && let Some(into_iter_did) = cx.tcx.get_diagnostic_item(sym::IntoIterator) + && let sig = cx.tcx.fn_sig(parent_fn_did).skip_binder().skip_binder() + && let Some(arg_pos) = args.iter().position(|x| x.hir_id == e.hir_id) + && let Some(&into_iter_param) = sig.inputs().get(kind.param_pos(arg_pos)) + && let ty::Param(param) = into_iter_param.kind() + && let Some(span) = into_iter_bound(cx, parent_fn_did, into_iter_did, param.index) +<<<<<<< HEAD +<<<<<<< HEAD + { + // Get the "innermost" `.into_iter()` call, e.g. given this expression: + // `foo.into_iter().into_iter()` + // ^^^ + let (into_iter_recv, depth) = into_iter_deep_call(cx, into_iter_recv); + + let plural = if depth == 0 { "" } else { "s" }; +======= + // Get the "innermost" `.into_iter()` call, e.g. given this expression: + // `foo.into_iter().into_iter()` + // ^^^ + // We want this span + && let Some(into_iter_recv) = into_iter_deep_call(cx, into_iter_recv) + { +>>>>>>> de1f41001 (merge `explicit_into_iter_fn_arg` into `useless_conversion`) +======= + { + // Get the "innermost" `.into_iter()` call, e.g. given this expression: + // `foo.into_iter().into_iter()` + // ^^^ + let (into_iter_recv, depth) = into_iter_deep_call(cx, into_iter_recv); + + let plural = if depth == 0 { "" } else { "s" }; +>>>>>>> 5a7e33e5b (add plural form to useless_conversion if depth > 0) + let mut applicability = Applicability::MachineApplicable; + let sugg = snippet_with_applicability(cx, into_iter_recv.span.source_callsite(), "", &mut applicability).into_owned(); + span_lint_and_then(cx, USELESS_CONVERSION, e.span, "explicit call to `.into_iter()` in function argument accepting `IntoIterator`", |diag| { + diag.span_suggestion( + e.span, +<<<<<<< HEAD +<<<<<<< HEAD + format!("consider removing the `.into_iter()`{plural}"), +======= + "consider removing `.into_iter()`", +>>>>>>> de1f41001 (merge `explicit_into_iter_fn_arg` into `useless_conversion`) +======= + format!("consider removing the `.into_iter()`{plural}"), +>>>>>>> 5a7e33e5b (add plural form to useless_conversion if depth > 0) + sugg, + applicability, + ); + diag.span_note(span, "this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`"); + }); + + // Early return to avoid linting again with contradicting suggestions + return; + } + } + + if let Some(id) = path_to_local(recv) && let Node::Pat(pat) = cx.tcx.hir().get(id) && let PatKind::Binding(ann, ..) = pat.kind && ann != BindingAnnotation::MUT @@ -138,6 +303,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { if_chain! { if let ExprKind::Path(ref qpath) = path.kind; if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id(); + if !is_ty_alias(qpath); then { let a = cx.typeck_results().expr_ty(e); let b = cx.typeck_results().expr_ty(arg); diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index bc4adf1596d4..c8892bd29231 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -304,6 +304,11 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("ByteStr(ref {vec})"); chain!(self, "let [{:?}] = **{vec}", vec.value); }, + LitKind::CStr(ref vec, _) => { + bind!(self, vec); + kind!("CStr(ref {vec})"); + chain!(self, "let [{:?}] = **{vec}", vec.value); + }, LitKind::Str(s, _) => { bind!(self, s); kind!("Str({s}, _)"); @@ -333,7 +338,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { #[allow(clippy::too_many_lines)] fn expr(&self, expr: &Binding<&hir::Expr<'_>>) { - if let Some(higher::While { condition, body }) = higher::While::hir(expr.value) { + if let Some(higher::While { condition, body, .. }) = higher::While::hir(expr.value) { bind!(self, condition, body); chain!( self, @@ -430,7 +435,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("Unary(UnOp::{op:?}, {inner})"); self.expr(inner); }, - ExprKind::Lit(ref lit) => { + ExprKind::Lit(lit) => { bind!(self, lit); kind!("Lit(ref {lit})"); self.lit(lit); @@ -554,10 +559,27 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("Ret({value})"); value.if_some(|e| self.expr(e)); }, + ExprKind::Become(value) => { + bind!(self, value); + kind!("Become({value})"); + self.expr(value); + }, ExprKind::InlineAsm(_) => { kind!("InlineAsm(_)"); out!("// unimplemented: `ExprKind::InlineAsm` is not further destructured at the moment"); }, + ExprKind::OffsetOf(container, ref fields) => { + bind!(self, container, fields); + kind!("OffsetOf({container}, {fields})"); +<<<<<<< HEAD + } +======= +<<<<<<< HEAD + }, +======= + } +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) ExprKind::Struct(qpath, fields, base) => { bind!(self, qpath, fields); opt_bind!(self, base); diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 896a01af37d9..5417804d4e93 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -2,12 +2,15 @@ #![allow(clippy::module_name_repetitions)] +use rustc_session::Session; +use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext}; use serde::de::{Deserializer, IgnoredAny, IntoDeserializer, MapAccess, Visitor}; use serde::Deserialize; -use std::error::Error; +use std::fmt::{Debug, Display, Formatter}; +use std::ops::Range; use std::path::{Path, PathBuf}; use std::str::FromStr; -use std::{cmp, env, fmt, fs, io, iter}; +use std::{cmp, env, fmt, fs, io}; #[rustfmt::skip] const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[ @@ -18,6 +21,7 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[ "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", + "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", @@ -31,6 +35,19 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[ "CamelCase", ]; const DEFAULT_DISALLOWED_NAMES: &[&str] = &["foo", "baz", "quux"]; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z", "w", "n"]; +======= +const DEFAULT_ALLOWED_IDENTS: &[char] = &['i', 'j', 'x', 'y', 'z', 'n']; +>>>>>>> 52cfc997a (Add lint `single_letter_idents`) +======= +const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z", "n"]; +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z", "w", "n"]; +>>>>>>> 243943ff5 (make it work for locals as well) /// Holds information used by `MISSING_ENFORCED_IMPORT_RENAMES` lint. #[derive(Clone, Debug, Deserialize)] @@ -67,33 +84,70 @@ impl DisallowedPath { #[derive(Default)] pub struct TryConf { pub conf: Conf, - pub errors: Vec>, - pub warnings: Vec>, + pub errors: Vec, + pub warnings: Vec, } impl TryConf { - fn from_error(error: impl Error + 'static) -> Self { + fn from_toml_error(file: &SourceFile, error: &toml::de::Error) -> Self { + ConfError::from_toml(file, error).into() + } +} + +impl From for TryConf { + fn from(value: ConfError) -> Self { Self { conf: Conf::default(), - errors: vec![Box::new(error)], + errors: vec![value], warnings: vec![], } } } +impl From for TryConf { + fn from(value: io::Error) -> Self { + ConfError::from(value).into() + } +} + #[derive(Debug)] -struct ConfError(String); +pub struct ConfError { + pub message: String, + pub span: Option, +} + +impl ConfError { + fn from_toml(file: &SourceFile, error: &toml::de::Error) -> Self { + if let Some(span) = error.span() { + Self::spanned(file, error.message(), span) + } else { + Self { + message: error.message().to_string(), + span: None, + } + } + } -impl fmt::Display for ConfError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ::fmt(&self.0, f) + fn spanned(file: &SourceFile, message: impl Into, span: Range) -> Self { + Self { + message: message.into(), + span: Some(Span::new( + file.start_pos + BytePos::from_usize(span.start), + file.start_pos + BytePos::from_usize(span.end), + SyntaxContext::root(), + None, + )), + } } } -impl Error for ConfError {} - -fn conf_error(s: impl Into) -> Box { - Box::new(ConfError(s.into())) +impl From for ConfError { + fn from(value: io::Error) -> Self { + Self { + message: value.to_string(), + span: None, + } + } } macro_rules! define_Conf { @@ -117,20 +171,14 @@ macro_rules! define_Conf { } } - impl<'de> Deserialize<'de> for TryConf { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - deserializer.deserialize_map(ConfVisitor) - } - } - #[derive(Deserialize)] #[serde(field_identifier, rename_all = "kebab-case")] #[allow(non_camel_case_types)] enum Field { $($name,)* third_party, } - struct ConfVisitor; + struct ConfVisitor<'a>(&'a SourceFile); - impl<'de> Visitor<'de> for ConfVisitor { + impl<'de> Visitor<'de> for ConfVisitor<'_> { type Value = TryConf; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -141,32 +189,38 @@ macro_rules! define_Conf { let mut errors = Vec::new(); let mut warnings = Vec::new(); $(let mut $name = None;)* - // could get `Field` here directly, but get `str` first for diagnostics - while let Some(name) = map.next_key::<&str>()? { - match Field::deserialize(name.into_deserializer())? { - $(Field::$name => { - $(warnings.push(conf_error(format!("deprecated field `{}`. {}", name, $dep)));)? - match map.next_value() { - Err(e) => errors.push(conf_error(e.to_string())), + // could get `Field` here directly, but get `String` first for diagnostics + while let Some(name) = map.next_key::>()? { + match Field::deserialize(name.get_ref().as_str().into_deserializer()) { + Err(e) => { + let e: FieldError = e; + errors.push(ConfError::spanned(self.0, e.0, name.span())); + } + $(Ok(Field::$name) => { + $(warnings.push(ConfError::spanned(self.0, format!("deprecated field `{}`. {}", name.get_ref(), $dep), name.span()));)? + let raw_value = map.next_value::>()?; + let value_span = raw_value.span(); + match <$ty>::deserialize(raw_value.into_inner()) { + Err(e) => errors.push(ConfError::spanned(self.0, e.to_string().replace('\n', " ").trim(), value_span)), Ok(value) => match $name { - Some(_) => errors.push(conf_error(format!("duplicate field `{}`", name))), + Some(_) => errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), name.span())), None => { $name = Some(value); // $new_conf is the same as one of the defined `$name`s, so // this variable is defined in line 2 of this function. $(match $new_conf { - Some(_) => errors.push(conf_error(concat!( + Some(_) => errors.push(ConfError::spanned(self.0, concat!( "duplicate field `", stringify!($new_conf), "` (provided as `", stringify!($name), "`)" - ))), + ), name.span())), None => $new_conf = $name.clone(), })? }, } } })* - // white-listed; ignore - Field::third_party => drop(map.next_value::()) + // ignore contents of the third_party key + Ok(Field::third_party) => drop(map.next_value::()) } } let conf = Conf { $($name: $name.unwrap_or_else(defaults::$name),)* }; @@ -174,16 +228,15 @@ macro_rules! define_Conf { } } - #[cfg(feature = "internal")] pub mod metadata { - use crate::utils::internal_lints::metadata_collector::ClippyConfiguration; + use crate::utils::ClippyConfiguration; macro_rules! wrap_option { () => (None); ($x:literal) => (Some($x)); } - pub(crate) fn get_configuration_metadata() -> Vec { + pub fn get_configuration_metadata() -> Vec { vec![ $( { @@ -249,11 +302,27 @@ define_Conf! { /// arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"] /// ``` (arithmetic_side_effects_allowed_unary: rustc_data_structures::fx::FxHashSet = <_>::default()), - /// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UNUSED_SELF, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_COLLECTION, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX, UNNECESSARY_BOX_RETURNS. + /// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UNUSED_SELF, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_COLLECTION, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX, UNNECESSARY_BOX_RETURNS, SINGLE_CALL_FN. /// /// Suppress lints whenever the suggested change would cause breakage for other crates. (avoid_breaking_exported_api: bool = true), - /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN. +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD. +======= + /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS. +>>>>>>> 33b6d0d20 (rename MSRV alias, add MSRV to lint doc) +======= + /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS. +>>>>>>> 211278bc8 (updated list of lints that use msrv) +======= + /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS. +>>>>>>> b1acbde61 (Add msrv check and make test pass) +======= + /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD. +>>>>>>> cb5d7e344 (address comments) /// /// The minimum rust version that the project supports (msrv: Option = None), @@ -266,6 +335,36 @@ define_Conf! { /// /// The maximum cognitive complexity a function can have (cognitive_complexity_threshold: u64 = 25), +<<<<<<< HEAD +<<<<<<< HEAD + /// Lint: EXCESSIVE_NESTING. + /// + /// The maximum amount of nesting a block can reside in + (excessive_nesting_threshold: u64 = 0), +======= + /// Lint: EXCESSIVE_WIDTH. + /// + /// The maximum width a statement can have + (excessive_width_threshold: u64 = 100), + /// Lint: EXCESSIVE_WIDTH. + /// + /// Whether to ignore the line's indentation + (excessive_width_ignore_indentation: bool = true), + /// Lint: EXCESSIVE_INDENTATION. + /// + /// The maximum indentation a statement can have + (excessive_indentation_threshold: u64 = 10), +>>>>>>> 97c10075e (add the `excessive_*` style lints) +======= + /// Lint: EXCESSIVE_NESTING. + /// + /// The maximum amount of nesting a block can reside in +<<<<<<< HEAD + (excessive_nesting_threshold: u64 = 10), +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + (excessive_nesting_threshold: u64 = 0), +>>>>>>> 725399a17 (move to `complexity` but don't lint by default) /// DEPRECATED LINT: CYCLOMATIC_COMPLEXITY. /// /// Use the Cognitive Complexity lint instead. @@ -274,9 +373,33 @@ define_Conf! { /// Lint: DISALLOWED_NAMES. /// /// The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value - /// `".."` can be used as part of the list to indicate, that the configured values should be appended to the + /// `".."` can be used as part of the list to indicate that the configured values should be appended to the /// default configuration of Clippy. By default, any configuration will replace the default value. (disallowed_names: Vec = super::DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect()), + /// Lint: SEMICOLON_INSIDE_BLOCK. + /// + /// Whether to lint only if it's multiline. +<<<<<<< HEAD +<<<<<<< HEAD + (semicolon_inside_block_ignore_singleline: bool = false), + /// Lint: SEMICOLON_OUTSIDE_BLOCK. + /// + /// Whether to lint only if it's singleline. + (semicolon_outside_block_ignore_multiline: bool = false), +======= + (semicolon_inside_block_if_multiline: bool = false), + /// Lint: SEMICOLON_OUTSIDE_BLOCK. + /// + /// Whether to lint only if it's singleline. + (semicolon_outside_block_if_singleline: bool = false), +>>>>>>> 41f6d88be (make cargo test pass) +======= + (semicolon_inside_block_ignore_singleline: bool = false), + /// Lint: SEMICOLON_OUTSIDE_BLOCK. + /// + /// Whether to lint only if it's singleline. + (semicolon_outside_block_ignore_multiline: bool = false), +>>>>>>> aa6c27a74 (change names to not be implicitly negative) /// Lint: DOC_MARKDOWN. /// /// The list of words this lint should not consider as identifiers needing ticks. The value @@ -335,6 +458,10 @@ define_Conf! { /// /// The maximum allowed size for arrays on the stack (array_size_threshold: u64 = 512_000), + /// Lint: LARGE_STACK_FRAMES. + /// + /// The maximum allowed stack size for functions in bytes + (stack_size_threshold: u64 = 512_000), /// Lint: VEC_BOX. /// /// The size of the boxed type in bytes, where boxing in a `Vec` is allowed @@ -463,6 +590,152 @@ define_Conf! { /// /// The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint (future_size_threshold: u64 = 16 * 1024), +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) +======= +======= +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + /// Lint: UNNECESSARY_BOX_RETURNS. + /// + /// The byte size a `T` in `Box` can have, below which it triggers the `clippy::unnecessary_box` lint + (unnecessary_box_size: u64 = 128), +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +======= +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) + /// Lint: SEMICOLON_INSIDE_BLOCK. + /// + /// Whether to lint only if it's multiline. + (semicolon_inside_block_if_multiline: bool = false), + /// Lint: SEMICOLON_OUTSIDE_BLOCK. + /// + /// Whether to lint only if it's singleline. + (semicolon_outside_block_if_singleline: bool = false), +<<<<<<< HEAD +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= +>>>>>>> 41f6d88be (make cargo test pass) +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) +======= +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= +>>>>>>> 41f6d88be (make cargo test pass) +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) + /// Lint: MODULE_INCEPTION. + /// + /// Whether to allow module inception if it's not public. + (allow_private_module_inception: bool = false), +<<<<<<< HEAD +<<<<<<< HEAD + /// Lint: MIN_IDENT_CHARS. + /// + /// Allowed names below the minimum allowed characters. The value `".."` can be used as part of + /// the list to indicate, that the configured values should be appended to the default + /// configuration of Clippy. By default, any configuration will replace the default value. +======= + /// Lint: MIN_IDENT_CHARS. + /// +<<<<<<< HEAD + /// Allowed names below the minimum allowed characters. +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + /// Allowed names below the minimum allowed characters. The value `".."` can be used as part of + /// the list to indicate, that the configured values should be appended to the default + /// configuration of Clippy. By default, any configuration will replace the default value. +>>>>>>> 95d1bff22 (add to tests and configuration) + (allowed_idents_below_min_chars: rustc_data_structures::fx::FxHashSet = + super::DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string).collect()), + /// Lint: MIN_IDENT_CHARS. + /// + /// Minimum chars an ident can have, anything below or equal to this will be linted. + (min_ident_chars_threshold: u64 = 1), +<<<<<<< HEAD +<<<<<<< HEAD + /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS. + /// + /// Whether to accept a safety comment to be placed above the statement containing the `unsafe` block + (accept_comment_above_statement: bool = false), +<<<<<<< HEAD +<<<<<<< HEAD + /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS. + /// + /// Whether to accept a safety comment to be placed above the attributes for the `unsafe` block + (accept_comment_above_attributes: bool = false), + /// Lint: UNNECESSARY_RAW_STRING_HASHES. + /// + /// Whether to allow `r#""#` when `r""` can be used + (allow_one_hash_in_raw_strings: bool = false), +======= +>>>>>>> b303e2053 (allow disabling module inception on private modules) +======= +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS. + /// + /// Whether to accept a safety comment to be placed above the statement containing the `unsafe` block + (accept_comment_above_statement: bool = false), +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= + /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS. + /// + /// Whether to accept a safety comment to be placed above the attributes for the `unsafe` block + (accept_comment_above_attributes: bool = false), +>>>>>>> cc2e49f69 (allow safety comment above attributes) +======= + /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS. + /// + /// Whether to accept a safety comment to be placed above the attributes for the `unsafe` block + (accept_comment_above_attributes: bool = false), + /// Lint: UNNECESSARY_RAW_STRING_HASHES. + /// + /// Whether to allow `r#""#` when `r""` can be used +<<<<<<< HEAD + (allow_one_hash_in_raw_string: bool = false), +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= + (allow_one_hash_in_raw_strings: bool = false), +>>>>>>> 8cb6c8699 (change category and refactor) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +======= + /// Lint: SEMICOLON_INSIDE_BLOCK. + /// + /// Whether to lint only if it's multiline. + (semicolon_inside_block_if_multiline: bool = false), + /// Lint: SEMICOLON_OUTSIDE_BLOCK. + /// + /// Whether to lint only if it's singleline. + (semicolon_outside_block_if_singleline: bool = false), +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= +>>>>>>> 41f6d88be (make cargo test pass) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) } /// Search for the configuration file. @@ -475,7 +748,7 @@ pub fn lookup_conf_file() -> io::Result<(Option, Vec)> { const CONFIG_FILE_NAMES: [&str; 2] = [".clippy.toml", "clippy.toml"]; // Start looking for a config file in CLIPPY_CONF_DIR, or failing that, CARGO_MANIFEST_DIR. - // If neither of those exist, use ".". + // If neither of those exist, use ".". (Update documentation if this priority changes) let mut current = env::var_os("CLIPPY_CONF_DIR") .or_else(|| env::var_os("CARGO_MANIFEST_DIR")) .map_or_else(|| PathBuf::from("."), PathBuf::from) @@ -521,19 +794,25 @@ pub fn lookup_conf_file() -> io::Result<(Option, Vec)> { /// Read the `toml` configuration file. /// /// In case of error, the function tries to continue as much as possible. -pub fn read(path: &Path) -> TryConf { - let content = match fs::read_to_string(path) { - Err(e) => return TryConf::from_error(e), - Ok(content) => content, +pub fn read(sess: &Session, path: &Path) -> TryConf { + let file = match sess.source_map().load_file(path) { + Err(e) => return e.into(), + Ok(file) => file, }; - match toml::from_str::(&content) { + match toml::de::Deserializer::new(file.src.as_ref().unwrap()).deserialize_map(ConfVisitor(&file)) { Ok(mut conf) => { extend_vec_if_indicator_present(&mut conf.conf.doc_valid_idents, DEFAULT_DOC_VALID_IDENTS); extend_vec_if_indicator_present(&mut conf.conf.disallowed_names, DEFAULT_DISALLOWED_NAMES); + // TODO: THIS SHOULD BE TESTED, this comment will be gone soon + if conf.conf.allowed_idents_below_min_chars.contains(&"..".to_owned()) { + conf.conf + .allowed_idents_below_min_chars + .extend(DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string)); + } conf }, - Err(e) => TryConf::from_error(e), + Err(e) => TryConf::from_toml_error(&file, &e), } } @@ -545,65 +824,42 @@ fn extend_vec_if_indicator_present(vec: &mut Vec, default: &[&str]) { const SEPARATOR_WIDTH: usize = 4; -// Check whether the error is "unknown field" and, if so, list the available fields sorted and at -// least one per line, more if `CLIPPY_TERMINAL_WIDTH` is set and allows it. -pub fn format_error(error: Box) -> String { - let s = error.to_string(); - - if_chain! { - if error.downcast::().is_ok(); - if let Some((prefix, mut fields, suffix)) = parse_unknown_field_message(&s); - then { - use fmt::Write; - - fields.sort_unstable(); - - let (rows, column_widths) = calculate_dimensions(&fields); - - let mut msg = String::from(prefix); - for row in 0..rows { - writeln!(msg).unwrap(); - for (column, column_width) in column_widths.iter().copied().enumerate() { - let index = column * rows + row; - let field = fields.get(index).copied().unwrap_or_default(); - write!( - msg, - "{:SEPARATOR_WIDTH$}{field:column_width$}", - " " - ) - .unwrap(); - } - } - write!(msg, "\n{suffix}").unwrap(); - msg - } else { - s - } +#[derive(Debug)] +struct FieldError(String); + +impl std::error::Error for FieldError {} + +impl Display for FieldError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.pad(&self.0) } } -// `parse_unknown_field_message` will become unnecessary if -// https://github.com/alexcrichton/toml-rs/pull/364 is merged. -fn parse_unknown_field_message(s: &str) -> Option<(&str, Vec<&str>, &str)> { - // An "unknown field" message has the following form: - // unknown field `UNKNOWN`, expected one of `FIELD0`, `FIELD1`, ..., `FIELDN` at line X column Y - // ^^ ^^^^ ^^ - if_chain! { - if s.starts_with("unknown field"); - let slices = s.split("`, `").collect::>(); - let n = slices.len(); - if n >= 2; - if let Some((prefix, first_field)) = slices[0].rsplit_once(" `"); - if let Some((last_field, suffix)) = slices[n - 1].split_once("` "); - then { - let fields = iter::once(first_field) - .chain(slices[1..n - 1].iter().copied()) - .chain(iter::once(last_field)) - .collect::>(); - Some((prefix, fields, suffix)) - } else { - None +impl serde::de::Error for FieldError { + fn custom(msg: T) -> Self { + Self(msg.to_string()) + } + + fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self { + // List the available fields sorted and at least one per line, more if `CLIPPY_TERMINAL_WIDTH` is + // set and allows it. + use fmt::Write; + + let mut expected = expected.to_vec(); + expected.sort_unstable(); + + let (rows, column_widths) = calculate_dimensions(&expected); + + let mut msg = format!("unknown field `{field}`, expected one of"); + for row in 0..rows { + writeln!(msg).unwrap(); + for (column, column_width) in column_widths.iter().copied().enumerate() { + let index = column * rows + row; + let field = expected.get(index).copied().unwrap_or_default(); + write!(msg, "{:SEPARATOR_WIDTH$}{field:column_width$}", " ").unwrap(); + } } + Self(msg) } } diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index 71f6c9909ddd..e222a5448c9c 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -1,3 +1,4 @@ +pub mod almost_standard_lint_formulation; pub mod clippy_lints_internal; pub mod collapsible_calls; pub mod compiler_lint_functions; diff --git a/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs b/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs new file mode 100644 index 000000000000..10957db8aa12 --- /dev/null +++ b/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs @@ -0,0 +1,95 @@ +use crate::utils::internal_lints::lint_without_lint_pass::is_lint_ref_type; +use clippy_utils::diagnostics::span_lint_and_help; +use regex::Regex; +use rustc_ast as ast; +use rustc_hir::{Item, ItemKind, Mutability}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; + +declare_clippy_lint! { + /// ### What it does + /// Checks if lint formulations have a standardized format. + /// + /// ### Why is this bad? + /// It's not neccessarily bad, but we try to enforce a standard in Clippy. + /// + /// ### Example + /// `Checks for use...` can be written as `Checks for usage...` . + pub ALMOST_STANDARD_LINT_FORMULATION, + internal, + "lint formulations must have a standardized format." +} + +impl_lint_pass!(AlmostStandardFormulation => [ALMOST_STANDARD_LINT_FORMULATION]); + +pub struct AlmostStandardFormulation { + standard_formulations: Vec>, +} + +#[derive(Debug)] +struct StandardFormulations<'a> { + wrong_pattern: Regex, + correction: &'a str, +} + +impl AlmostStandardFormulation { + pub fn new() -> Self { + let standard_formulations = vec![StandardFormulations { +<<<<<<< HEAD +<<<<<<< HEAD + wrong_pattern: Regex::new("^(Check for|Detects? uses?)").unwrap(), +======= + wrong_pattern: Regex::new(r"^(Check for|Detects? uses?)").unwrap(), +>>>>>>> 7ac15f900 (Add lint to check lint formulation messages) +======= + wrong_pattern: Regex::new("^(Check for|Detects? uses?)").unwrap(), +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) + correction: "Checks for", + }]; + Self { standard_formulations } + } +} + +impl<'tcx> LateLintPass<'tcx> for AlmostStandardFormulation { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { + let mut check_next = false; + if let ItemKind::Static(ty, Mutability::Not, _) = item.kind { + let lines = cx + .tcx + .hir() + .attrs(item.hir_id()) + .iter() + .filter_map(|attr| ast::Attribute::doc_str(attr).map(|sym| (sym, attr))); + if is_lint_ref_type(cx, ty) { + for (line, attr) in lines { + let cur_line = line.as_str().trim(); + if check_next && !cur_line.is_empty() { + for formulation in &self.standard_formulations { + let starts_with_correct_formulation = cur_line.starts_with(formulation.correction); + if !starts_with_correct_formulation && formulation.wrong_pattern.is_match(cur_line) { + if let Some(ident) = attr.ident() { + span_lint_and_help( + cx, + ALMOST_STANDARD_LINT_FORMULATION, + ident.span, + "non-standard lint formulation", + None, + &format!("try using `{}` instead", formulation.correction), + ); + } + return; + } + } + return; + } else if cur_line.contains("What it does") { + check_next = true; + } else if cur_line.contains("Why is this bad") { + // Formulation documentation is done. Can add check to ensure that missing formulation is added + // and add a check if it matches no accepted formulation + return; + } + } + } + } + } +} diff --git a/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs b/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs index f8978e30a8e2..dced9fcf9abd 100644 --- a/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs +++ b/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs @@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol { for &module in &[&paths::KW_MODULE, &paths::SYM_MODULE] { for def_id in def_path_def_ids(cx, module) { - for item in cx.tcx.module_children(def_id).iter() { + for item in cx.tcx.module_children(def_id) { if_chain! { if let Res::Def(DefKind::Const, item_def_id) = item.res; let ty = cx.tcx.type_of(item_def_id).subst_identity(); diff --git a/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/clippy_lints/src/utils/internal_lints/invalid_paths.rs index 9afe02c1e47d..94b56304bcab 100644 --- a/clippy_lints/src/utils/internal_lints/invalid_paths.rs +++ b/clippy_lints/src/utils/internal_lints/invalid_paths.rs @@ -7,7 +7,8 @@ use rustc_hir::def::DefKind; use rustc_hir::Item; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{self, fast_reject::SimplifiedType, FloatTy}; +use rustc_middle::ty::fast_reject::SimplifiedType; +use rustc_middle::ty::{self, FloatTy}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::Symbol; diff --git a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index f718207654f4..87380f14f9a4 100644 --- a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -3,10 +3,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; use clippy_utils::macros::root_macro_call_first_node; use clippy_utils::{is_lint_allowed, match_def_path, paths}; use if_chain::if_chain; -use rustc_ast as ast; use rustc_ast::ast::LitKind; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::hir_id::CRATE_HIR_ID; use rustc_hir::intravisit::Visitor; @@ -18,6 +16,7 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Spanned; use rustc_span::symbol::Symbol; use rustc_span::{sym, Span}; +use {rustc_ast as ast, rustc_hir as hir}; declare_clippy_lint! { /// ### What it does diff --git a/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/clippy_lints/src/utils/internal_lints/metadata_collector.rs index 3d0d4a52511a..1a828cf5aa4a 100644 --- a/clippy_lints/src/utils/internal_lints/metadata_collector.rs +++ b/clippy_lints/src/utils/internal_lints/metadata_collector.rs @@ -8,7 +8,16 @@ //! a simple mistake) use crate::renamed_lints::RENAMED_LINTS; +<<<<<<< HEAD use crate::utils::internal_lints::lint_without_lint_pass::{extract_clippy_version_value, is_lint_ref_type}; +use crate::utils::{collect_configs, ClippyConfiguration}; +======= +use crate::utils::{ + collect_configs, + internal_lints::lint_without_lint_pass::{extract_clippy_version_value, is_lint_ref_type}, + ClippyConfiguration, +}; +>>>>>>> e4f5d83fa (Fixed formatting.) use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::{match_type, walk_ptrs_ty_depth}; @@ -17,22 +26,22 @@ use if_chain::if_chain; use itertools::Itertools; use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; -use rustc_hir::{ - self as hir, def::DefKind, intravisit, intravisit::Visitor, Closure, ExprKind, Item, ItemKind, Mutability, QPath, -}; +use rustc_hir::def::DefKind; +use rustc_hir::intravisit::Visitor; +use rustc_hir::{self as hir, intravisit, Closure, ExprKind, Item, ItemKind, Mutability, QPath}; use rustc_lint::{CheckLintNameResult, LateContext, LateLintPass, LintContext, LintId}; use rustc_middle::hir::nested_filter; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::Ident; use rustc_span::{sym, Loc, Span, Symbol}; -use serde::{ser::SerializeStruct, Serialize, Serializer}; +use serde::ser::SerializeStruct; +use serde::{Serialize, Serializer}; use std::collections::{BTreeSet, BinaryHeap}; use std::fmt; use std::fmt::Write as _; use std::fs::{self, OpenOptions}; use std::io::prelude::*; -use std::path::Path; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::Command; /// This is the json output file of the lint collector. @@ -100,6 +109,8 @@ const APPLICABILITY_UNRESOLVED_STR: &str = "Unresolved"; /// The version that will be displayed if none has been defined const VERSION_DEFAULT_STR: &str = "Unknown"; +const CHANGELOG_PATH: &str = "../CHANGELOG.md"; + declare_clippy_lint! { /// ### What it does /// Collects metadata about clippy lints for the website. @@ -191,8 +202,14 @@ This lint has the following configuration variables: fn get_markdown_docs(&self) -> String { format!( - "## Lint Configuration Options\n|
Option
| Default Value |\n|--|--|\n{}\n\n{}\n", - self.configs_to_markdown(ClippyConfiguration::to_markdown_table_entry), + r#"# Lint Configuration Options + +The following list shows each configuration option, along with a description, its default value, an example +and lints affected. + +--- + +{}"#, self.configs_to_markdown(ClippyConfiguration::to_markdown_paragraph), ) } @@ -250,6 +267,22 @@ Please use that command to update the file and do not edit it by hand. self.get_markdown_docs(), ) .unwrap(); + + // Write configuration links to CHANGELOG.md + let mut changelog = std::fs::read_to_string(CHANGELOG_PATH).unwrap(); + let mut changelog_file = OpenOptions::new().read(true).write(true).open(CHANGELOG_PATH).unwrap(); + + if let Some(position) = changelog.find("") { + // I know this is kinda wasteful, we just don't have regex on `clippy_lints` so... this is the best + // we can do AFAIK. + changelog = changelog[..position].to_string(); + } + writeln!( + changelog_file, + "{changelog}\n{}\n", + self.configs_to_markdown(ClippyConfiguration::to_markdown_link) + ) + .unwrap(); } } @@ -520,111 +553,6 @@ impl Serialize for ApplicabilityInfo { } } -// ================================================================== -// Configuration -// ================================================================== -#[derive(Debug, Clone, Default)] -pub struct ClippyConfiguration { - name: String, - config_type: &'static str, - default: String, - lints: Vec, - doc: String, - #[allow(dead_code)] - deprecation_reason: Option<&'static str>, -} - -impl ClippyConfiguration { - pub fn new( - name: &'static str, - config_type: &'static str, - default: String, - doc_comment: &'static str, - deprecation_reason: Option<&'static str>, - ) -> Self { - let (lints, doc) = parse_config_field_doc(doc_comment) - .unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string())); - - Self { - name: to_kebab(name), - lints, - doc, - config_type, - default, - deprecation_reason, - } - } - - fn to_markdown_paragraph(&self) -> String { - format!( - "### {}\n{}\n\n**Default Value:** `{}` (`{}`)\n\n{}\n\n", - self.name, - self.doc - .lines() - .map(|line| line.strip_prefix(" ").unwrap_or(line)) - .join("\n"), - self.default, - self.config_type, - self.lints - .iter() - .map(|name| name.to_string().split_whitespace().next().unwrap().to_string()) - .map(|name| format!("* [{name}](https://rust-lang.github.io/rust-clippy/master/index.html#{name})")) - .join("\n"), - ) - } - - fn to_markdown_table_entry(&self) -> String { - format!("| [{}](#{}) | `{}` |", self.name, self.name, self.default) - } -} - -fn collect_configs() -> Vec { - crate::utils::conf::metadata::get_configuration_metadata() -} - -/// This parses the field documentation of the config struct. -/// -/// ```rust, ignore -/// parse_config_field_doc(cx, "Lint: LINT_NAME_1, LINT_NAME_2. Papa penguin, papa penguin") -/// ``` -/// -/// Would yield: -/// ```rust, ignore -/// Some(["lint_name_1", "lint_name_2"], "Papa penguin, papa penguin") -/// ``` -fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec, String)> { - const DOC_START: &str = " Lint: "; - if_chain! { - if doc_comment.starts_with(DOC_START); - if let Some(split_pos) = doc_comment.find('.'); - then { - let mut doc_comment = doc_comment.to_string(); - let mut documentation = doc_comment.split_off(split_pos); - - // Extract lints - doc_comment.make_ascii_lowercase(); - let lints: Vec = doc_comment - .split_off(DOC_START.len()) - .split(", ") - .map(str::to_string) - .collect(); - - // Format documentation correctly - // split off leading `.` from lint name list and indent for correct formatting - documentation = documentation.trim_start_matches('.').trim().replace("\n ", "\n "); - - Some((lints, documentation)) - } else { - None - } - } -} - -/// Transforms a given `snake_case_string` to a tasty `kebab-case-string` -fn to_kebab(config_name: &str) -> String { - config_name.replace('_', "-") -} - impl fmt::Display for ClippyConfiguration { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result { writeln!( diff --git a/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs index 09f0f0d0adb6..14855e9c3319 100644 --- a/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs +++ b/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs @@ -7,7 +7,8 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::ty::{self, subst::GenericArgKind}; +use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::{self}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index dc647af264c1..9fd3bd1dfae4 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -4,3 +4,173 @@ pub mod dump_hir; pub mod format_args_collector; #[cfg(feature = "internal")] pub mod internal_lints; +#[cfg(feature = "internal")] +use itertools::Itertools; + +/// Transforms a given `snake_case_string` to a tasty `kebab-case-string` +fn to_kebab(config_name: &str) -> String { + config_name.replace('_', "-") +} + +<<<<<<< HEAD +#[cfg(feature = "internal")] +const BOOK_CONFIGS_PATH: &str = "https://doc.rust-lang.org/clippy/lint_configuration.html"; + +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +// ================================================================== +// Configuration +// ================================================================== +#[derive(Debug, Clone, Default)] //~ ERROR no such field +pub struct ClippyConfiguration { + pub name: String, + #[allow(dead_code)] + config_type: &'static str, + pub default: String, + pub lints: Vec, + pub doc: String, + #[allow(dead_code)] + deprecation_reason: Option<&'static str>, +} + +impl ClippyConfiguration { + pub fn new( + name: &'static str, + config_type: &'static str, + default: String, + doc_comment: &'static str, + deprecation_reason: Option<&'static str>, + ) -> Self { + let (lints, doc) = parse_config_field_doc(doc_comment) + .unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string())); + + Self { + name: to_kebab(name), + lints, + doc, + config_type, + default, + deprecation_reason, + } + } + + #[cfg(feature = "internal")] + fn to_markdown_paragraph(&self) -> String { + format!( +<<<<<<< HEAD + "## `{}`\n{}\n\n**Default Value:** `{}` (`{}`)\n\n---\n**Affected lints:**\n{}\n\n", +======= + "### {}\n{}\n\n**Default Value:** `{}` (`{}`)\n\n{}\n\n", +>>>>>>> e4f5d83fa (Fixed formatting.) + self.name, + self.doc + .lines() + .map(|line| line.strip_prefix(" ").unwrap_or(line)) + .join("\n"), + self.default, + self.config_type, + self.lints + .iter() + .map(|name| name.to_string().split_whitespace().next().unwrap().to_string()) +<<<<<<< HEAD + .map(|name| format!("* [`{name}`](https://rust-lang.github.io/rust-clippy/master/index.html#{name})")) + .join("\n"), + ) + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> d5b2f1134 (Now `cargo collect-metadata` updates the `CHANGELOG.md`) + #[cfg(feature = "internal")] + fn to_markdown_link(&self) -> String { + format!("[`{}`]: {BOOK_CONFIGS_PATH}#{}", self.name, self.name) + } +<<<<<<< HEAD +======= +>>>>>>> b7a605471 (Refresh Lint Configuration's looks) +======= +>>>>>>> d5b2f1134 (Now `cargo collect-metadata` updates the `CHANGELOG.md`) +======= + .map(|name| format!("* [{name}](https://rust-lang.github.io/rust-clippy/master/index.html#{name})")) + .join("\n"), + ) + } + + #[cfg(feature = "internal")] + fn to_markdown_table_entry(&self) -> String { + format!("| [{}](#{}) | `{}` |", self.name, self.name, self.default) + } +>>>>>>> e4f5d83fa (Fixed formatting.) +} + +#[cfg(feature = "internal")] +fn collect_configs() -> Vec { + crate::utils::conf::metadata::get_configuration_metadata() +} + +/// This parses the field documentation of the config struct. +/// +/// ```rust, ignore +/// parse_config_field_doc(cx, "Lint: LINT_NAME_1, LINT_NAME_2. Papa penguin, papa penguin") +/// ``` +/// +/// Would yield: +/// ```rust, ignore +/// Some(["lint_name_1", "lint_name_2"], "Papa penguin, papa penguin") +/// ``` +fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec, String)> { + const DOC_START: &str = " Lint: "; + if_chain! { + if doc_comment.starts_with(DOC_START); + if let Some(split_pos) = doc_comment.find('.'); + then { + let mut doc_comment = doc_comment.to_string(); + let mut documentation = doc_comment.split_off(split_pos); + + // Extract lints + doc_comment.make_ascii_lowercase(); + let lints: Vec = doc_comment + .split_off(DOC_START.len()) + .split(", ") + .map(str::to_string) + .collect(); + + // Format documentation correctly + // split off leading `.` from lint name list and indent for correct formatting + documentation = documentation.trim_start_matches('.').trim().replace("\n ", "\n "); + + Some((lints, documentation)) + } else { + None + } + } +} + +// Shamelessly stolen from find_all (https://github.com/nectariner/find_all) +pub trait FindAll: Iterator + Sized { + fn find_all

(&mut self, predicate: P) -> Option> + where + P: FnMut(&Self::Item) -> bool; +} + +impl FindAll for I +where + I: Iterator, +{ + fn find_all

(&mut self, mut predicate: P) -> Option> + where + P: FnMut(&Self::Item) -> bool, + { + let mut occurences = Vec::::default(); + for (index, element) in self.enumerate() { + if predicate(&element) { + occurences.push(index); + } + } + + match occurences.len() { + 0 => None, + _ => Some(occurences), + } + } +} diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 297a80e5767a..8ac2bbbab512 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -1,26 +1,39 @@ +use std::ops::ControlFlow; + use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::higher; +<<<<<<< HEAD +<<<<<<< HEAD +use clippy_utils::msrvs::{self, Msrv}; +======= +>>>>>>> 566a365d4 (make `useless_vec` smarter) +======= +use clippy_utils::msrvs::{self, Msrv}; +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_copy; +use clippy_utils::visitors::for_each_local_use_after_expr; +use clippy_utils::{get_parent_expr, higher, is_trait_method}; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability}; +use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Node, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; +use rustc_span::sym; #[expect(clippy::module_name_repetitions)] -#[derive(Copy, Clone)] +#[derive(Clone)] pub struct UselessVec { pub too_large_for_stack: u64, + pub msrv: Msrv, } declare_clippy_lint! { /// ### What it does - /// Checks for usage of `&vec![..]` when using `&[..]` would + /// Checks for usage of `vec![..]` when using `[..]` would /// be possible. /// /// ### Why is this bad? @@ -46,16 +59,134 @@ declare_clippy_lint! { impl_lint_pass!(UselessVec => [USELESS_VEC]); +fn adjusts_to_slice(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { +<<<<<<< HEAD +<<<<<<< HEAD + matches!(cx.typeck_results().expr_ty_adjusted(e).kind(), ty::Ref(_, ty, _) if ty.is_slice()) +======= + if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(e).kind() { + ty.is_slice() + } else { + false + } +>>>>>>> 566a365d4 (make `useless_vec` smarter) +======= + matches!(cx.typeck_results().expr_ty_adjusted(e).kind(), ty::Ref(_, ty, _) if ty.is_slice()) +>>>>>>> b309875fd ([`useless_vec`]: detect unnecessary `vec![_]`) +} + +/// Checks if the given expression is a method call to a `Vec` method +/// that also exists on slices. If this returns true, it means that +/// this expression does not actually require a `Vec` and could just work with an array. +fn is_allowed_vec_method(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { +<<<<<<< HEAD +<<<<<<< HEAD + const ALLOWED_METHOD_NAMES: &[&str] = &["len", "as_ptr", "is_empty"]; +======= + const ALLOWED_METHOD_NAMES: &[&str] = &["len", "as_ptr", "as_slice", "is_empty"]; +>>>>>>> 566a365d4 (make `useless_vec` smarter) +======= + const ALLOWED_METHOD_NAMES: &[&str] = &["len", "as_ptr", "is_empty"]; +>>>>>>> 7af77f74d (don't allow `as_slice` for now) + + if let ExprKind::MethodCall(path, ..) = e.kind { + ALLOWED_METHOD_NAMES.contains(&path.ident.name.as_str()) + } else { + is_trait_method(cx, e, sym::IntoIterator) + } +} + impl<'tcx> LateLintPass<'tcx> for UselessVec { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - // search for `&vec![_]` expressions where the adjusted type is `&[_]` + // search for `&vec![_]` or `vec![_]` expressions where the adjusted type is `&[_]` if_chain! { - if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(expr).kind(); - if let ty::Slice(..) = ty.kind(); + if adjusts_to_slice(cx, expr); +<<<<<<< HEAD +<<<<<<< HEAD + if let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()); + then { + let (suggest_slice, span) = if let ExprKind::AddrOf(BorrowKind::Ref, mutability, _) = expr.kind { + // `expr` is `&vec![_]`, so suggest `&[_]` (or `&mut[_]` resp.) + (SuggestedType::SliceRef(mutability), expr.span) + } else { + // `expr` is the `vec![_]` expansion, so suggest `[_]` + // and also use the span of the actual `vec![_]` expression + (SuggestedType::Array, expr.span.ctxt().outer_expn_data().call_site) + }; + + self.check_vec_macro(cx, &vec_args, span, suggest_slice); +======= if let ExprKind::AddrOf(BorrowKind::Ref, mutability, addressee) = expr.kind; if let Some(vec_args) = higher::VecArgs::hir(cx, addressee); then { - self.check_vec_macro(cx, &vec_args, mutability, expr.span); + self.check_vec_macro(cx, &vec_args, mutability, expr.span, SuggestSlice::Yes); +>>>>>>> 566a365d4 (make `useless_vec` smarter) +======= + if let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()); + then { + let (suggest_slice, span) = if let ExprKind::AddrOf(BorrowKind::Ref, mutability, _) = expr.kind { + // `expr` is `&vec![_]`, so suggest `&[_]` (or `&mut[_]` resp.) + (SuggestedType::SliceRef(mutability), expr.span) + } else { + // `expr` is the `vec![_]` expansion, so suggest `[_]` + // and also use the span of the actual `vec![_]` expression + (SuggestedType::Array, expr.span.ctxt().outer_expn_data().call_site) + }; + + self.check_vec_macro(cx, &vec_args, span, suggest_slice); +>>>>>>> b309875fd ([`useless_vec`]: detect unnecessary `vec![_]`) + } + } + + // search for `let foo = vec![_]` expressions where all uses of `foo` + // adjust to slices or call a method that exist on slices (e.g. len) + if let Some(vec_args) = higher::VecArgs::hir(cx, expr) + && let Node::Local(local) = cx.tcx.hir().get_parent(expr.hir_id) + // for now ignore locals with type annotations. + // this is to avoid compile errors when doing the suggestion here: let _: Vec<_> = vec![..]; + && local.ty.is_none() +<<<<<<< HEAD +<<<<<<< HEAD + && let PatKind::Binding(_, id, ..) = local.pat.kind +======= + && let PatKind::Binding(BindingAnnotation(_, mutbl), id, ..) = local.pat.kind +>>>>>>> 566a365d4 (make `useless_vec` smarter) +======= + && let PatKind::Binding(_, id, ..) = local.pat.kind +>>>>>>> b309875fd ([`useless_vec`]: detect unnecessary `vec![_]`) + && is_copy(cx, vec_type(cx.typeck_results().expr_ty_adjusted(expr))) + { + let only_slice_uses = for_each_local_use_after_expr(cx, id, expr.hir_id, |expr| { + // allow indexing into a vec and some set of allowed method calls that exist on slices, too + if let Some(parent) = get_parent_expr(cx, expr) + && (adjusts_to_slice(cx, expr) + || matches!(parent.kind, ExprKind::Index(..)) + || is_allowed_vec_method(cx, parent)) + { + ControlFlow::Continue(()) + } else { + ControlFlow::Break(()) + } + }).is_continue(); + + if only_slice_uses { + self.check_vec_macro( + cx, + &vec_args, +<<<<<<< HEAD +<<<<<<< HEAD + expr.span.ctxt().outer_expn_data().call_site, + SuggestedType::Array +======= + mutbl, + expr.span.ctxt().outer_expn_data().call_site, + SuggestSlice::No +>>>>>>> 566a365d4 (make `useless_vec` smarter) +======= + expr.span.ctxt().outer_expn_data().call_site, + SuggestedType::Array +>>>>>>> b309875fd ([`useless_vec`]: detect unnecessary `vec![_]`) + ); } } @@ -63,48 +194,121 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec { if_chain! { if let Some(higher::ForLoop { arg, .. }) = higher::ForLoop::hir(expr); if let Some(vec_args) = higher::VecArgs::hir(cx, arg); - if is_copy(cx, vec_type(cx.typeck_results().expr_ty_adjusted(arg))); + if self.msrv.meets(msrvs::ARRAY_INTO_ITERATOR); then { // report the error around the `vec!` not inside `:` let span = arg.span.ctxt().outer_expn_data().call_site; - self.check_vec_macro(cx, &vec_args, Mutability::Not, span); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + self.check_vec_macro(cx, &vec_args, span, SuggestedType::Array); +======= + self.check_vec_macro(cx, &vec_args, Mutability::Not, span, SuggestSlice::Yes); +>>>>>>> 566a365d4 (make `useless_vec` smarter) +======= + self.check_vec_macro(cx, &vec_args, Mutability::Not, span, SuggestSlice::No); +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) +======= + self.check_vec_macro(cx, &vec_args, span, SuggestedType::Array); +>>>>>>> b309875fd ([`useless_vec`]: detect unnecessary `vec![_]`) } } } + + extract_msrv_attr!(LateContext); +<<<<<<< HEAD +} + +#[derive(Copy, Clone)] +enum SuggestedType { + /// Suggest using a slice `&[..]` / `&mut [..]` + SliceRef(Mutability), + /// Suggest using an array: `[..]` + Array, +======= +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) +} + +#[derive(Copy, Clone)] +enum SuggestedType { + /// Suggest using a slice `&[..]` / `&mut [..]` + SliceRef(Mutability), + /// Suggest using an array: `[..]` + Array, } impl UselessVec { fn check_vec_macro<'tcx>( - self, + &mut self, cx: &LateContext<'tcx>, vec_args: &higher::VecArgs<'tcx>, - mutability: Mutability, span: Span, +<<<<<<< HEAD +<<<<<<< HEAD + suggest_slice: SuggestedType, ) { + if span.from_expansion() { + return; + } + let mut applicability = Applicability::MachineApplicable; + +======= + suggest_slice: SuggestSlice, + ) { + let mut applicability = Applicability::MachineApplicable; + + let (borrow_prefix_mut, borrow_prefix) = match suggest_slice { + SuggestSlice::Yes => ("&mut ", "&"), + SuggestSlice::No => ("", ""), + }; + +>>>>>>> 566a365d4 (make `useless_vec` smarter) +======= + suggest_slice: SuggestedType, + ) { + let mut applicability = Applicability::MachineApplicable; + +>>>>>>> b309875fd ([`useless_vec`]: detect unnecessary `vec![_]`) let snippet = match *vec_args { higher::VecArgs::Repeat(elem, len) => { - if let Some((Constant::Int(len_constant), _)) = constant(cx, cx.typeck_results(), len) { + if let Some(Constant::Int(len_constant)) = constant(cx, cx.typeck_results(), len) { #[expect(clippy::cast_possible_truncation)] if len_constant as u64 * size_of(cx, elem) > self.too_large_for_stack { return; } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> b309875fd ([`useless_vec`]: detect unnecessary `vec![_]`) + let elem = snippet_with_applicability(cx, elem.span, "elem", &mut applicability); + let len = snippet_with_applicability(cx, len.span, "len", &mut applicability); + + match suggest_slice { + SuggestedType::SliceRef(Mutability::Mut) => format!("&mut [{elem}; {len}]"), + SuggestedType::SliceRef(Mutability::Not) => format!("&[{elem}; {len}]"), + SuggestedType::Array => format!("[{elem}; {len}]"), +<<<<<<< HEAD +======= match mutability { Mutability::Mut => { format!( - "&mut [{}; {}]", + "{borrow_prefix_mut}[{}; {}]", snippet_with_applicability(cx, elem.span, "elem", &mut applicability), snippet_with_applicability(cx, len.span, "len", &mut applicability) ) }, Mutability::Not => { format!( - "&[{}; {}]", + "{borrow_prefix}[{}; {}]", snippet_with_applicability(cx, elem.span, "elem", &mut applicability), snippet_with_applicability(cx, len.span, "len", &mut applicability) ) }, +>>>>>>> 566a365d4 (make `useless_vec` smarter) +======= +>>>>>>> b309875fd ([`useless_vec`]: detect unnecessary `vec![_]`) } } else { return; @@ -115,23 +319,59 @@ impl UselessVec { if args.len() as u64 * size_of(cx, last) > self.too_large_for_stack { return; } - let span = args[0].span.to(last.span); + let span = args[0].span.source_callsite().to(last.span.source_callsite()); + let args = snippet_with_applicability(cx, span, "..", &mut applicability); +<<<<<<< HEAD +<<<<<<< HEAD + match suggest_slice { + SuggestedType::SliceRef(Mutability::Mut) => { + format!("&mut [{args}]") + }, + SuggestedType::SliceRef(Mutability::Not) => { + format!("&[{args}]") + }, + SuggestedType::Array => { + format!("[{args}]") + }, + } + } else { + match suggest_slice { + SuggestedType::SliceRef(Mutability::Mut) => "&mut []".to_owned(), + SuggestedType::SliceRef(Mutability::Not) => "&[]".to_owned(), + SuggestedType::Array => "[]".to_owned(), +======= match mutability { Mutability::Mut => { format!( - "&mut [{}]", + "{borrow_prefix_mut}[{}]", snippet_with_applicability(cx, span, "..", &mut applicability) ) +======= + match suggest_slice { + SuggestedType::SliceRef(Mutability::Mut) => { + format!("&mut [{args}]") +>>>>>>> b309875fd ([`useless_vec`]: detect unnecessary `vec![_]`) }, - Mutability::Not => { - format!("&[{}]", snippet_with_applicability(cx, span, "..", &mut applicability)) + SuggestedType::SliceRef(Mutability::Not) => { + format!("&[{args}]") + }, + SuggestedType::Array => { + format!("[{args}]") }, } } else { +<<<<<<< HEAD match mutability { - Mutability::Mut => "&mut []".into(), - Mutability::Not => "&[]".into(), + Mutability::Mut => format!("{borrow_prefix_mut}[]"), + Mutability::Not => format!("{borrow_prefix}[]"), +>>>>>>> 566a365d4 (make `useless_vec` smarter) +======= + match suggest_slice { + SuggestedType::SliceRef(Mutability::Mut) => "&mut []".to_owned(), + SuggestedType::SliceRef(Mutability::Not) => "&[]".to_owned(), + SuggestedType::Array => "[]".to_owned(), +>>>>>>> b309875fd ([`useless_vec`]: detect unnecessary `vec![_]`) } } }, @@ -142,7 +382,23 @@ impl UselessVec { USELESS_VEC, span, "useless use of `vec!`", - "you can use a slice directly", + &format!( + "you can use {} directly", + match suggest_slice { +<<<<<<< HEAD +<<<<<<< HEAD + SuggestedType::SliceRef(_) => "a slice", + SuggestedType::Array => "an array", +======= + SuggestSlice::Yes => "a slice", + SuggestSlice::No => "an array", +>>>>>>> 566a365d4 (make `useless_vec` smarter) +======= + SuggestedType::SliceRef(_) => "a slice", + SuggestedType::Array => "an array", +>>>>>>> b309875fd ([`useless_vec`]: detect unnecessary `vec![_]`) + } + ), snippet, applicability, ); diff --git a/clippy_lints/src/visibility.rs b/clippy_lints/src/visibility.rs new file mode 100644 index 000000000000..dd5174ec8279 --- /dev/null +++ b/clippy_lints/src/visibility.rs @@ -0,0 +1,189 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_opt; +use rustc_ast::ast::{Item, VisibilityKind}; +use rustc_errors::Applicability; +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::symbol::kw; +use rustc_span::Span; + +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of `pub(self)` and `pub(in self)`. + /// + /// ### Why is this bad? + /// It's unnecessary, omitting the `pub` entirely will give the same results. + /// + /// ### Example + /// ```rust,ignore + /// pub(self) type OptBox = Option>; + /// ``` + /// Use instead: + /// ```rust,ignore + /// type OptBox = Option>; + /// ``` + #[clippy::version = "1.72.0"] + pub NEEDLESS_PUB_SELF, +<<<<<<< HEAD +<<<<<<< HEAD + style, +======= + complexity, +>>>>>>> 8296a338d (new lints for visibility) +======= + style, +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) + "checks for usage of `pub(self)` and `pub(in self)`." +} +declare_clippy_lint! { + /// ### What it does +<<<<<<< HEAD +<<<<<<< HEAD + /// Checks for usage of `pub()` with `in`. +======= + /// Checks for missing usage of the `pub(in )` shorthand. +>>>>>>> 8296a338d (new lints for visibility) +======= + /// Checks for usage of `pub()` with `in`. +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) + /// + /// ### Why is this bad? + /// Consistency. Use it or don't, just be consistent about it. + /// +<<<<<<< HEAD +<<<<<<< HEAD + /// Also see the `pub_without_shorthand` lint for an alternative. + /// +======= +>>>>>>> 8296a338d (new lints for visibility) +======= + /// Also see the `pub_without_shorthand` lint for an alternative. + /// +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) + /// ### Example + /// ```rust,ignore + /// pub(super) type OptBox = Option>; + /// ``` + /// Use instead: + /// ```rust,ignore + /// pub(in super) type OptBox = Option>; + /// ``` + #[clippy::version = "1.72.0"] + pub PUB_WITH_SHORTHAND, + restriction, +<<<<<<< HEAD +<<<<<<< HEAD + "disallows usage of `pub()`, without `in`" +} +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of `pub()` without `in`. +======= + "disallows usage of the `pub()`, suggesting use of the `in` shorthand" +} +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of the `pub(in )` shorthand. +>>>>>>> 8296a338d (new lints for visibility) +======= + "disallows usage of `pub()`, without `in`" +} +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of `pub()` without `in`. +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) + /// + /// Note: As you cannot write a module's path in `pub()`, this will only trigger on + /// `pub(super)` and the like. + /// + /// ### Why is this bad? + /// Consistency. Use it or don't, just be consistent about it. + /// +<<<<<<< HEAD +<<<<<<< HEAD + /// Also see the `pub_with_shorthand` lint for an alternative. + /// +======= +>>>>>>> 8296a338d (new lints for visibility) +======= + /// Also see the `pub_with_shorthand` lint for an alternative. + /// +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) + /// ### Example + /// ```rust,ignore + /// pub(in super) type OptBox = Option>; + /// ``` + /// Use instead: + /// ```rust,ignore + /// pub(super) type OptBox = Option>; + /// ``` + #[clippy::version = "1.72.0"] + pub PUB_WITHOUT_SHORTHAND, + restriction, +<<<<<<< HEAD +<<<<<<< HEAD + "disallows usage of `pub(in )` with `in`" +======= + "disallows usage of the `pub(in )` shorthand wherever possible" +>>>>>>> 8296a338d (new lints for visibility) +======= + "disallows usage of `pub(in )` with `in`" +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) +} +declare_lint_pass!(Visibility => [NEEDLESS_PUB_SELF, PUB_WITH_SHORTHAND, PUB_WITHOUT_SHORTHAND]); + +impl EarlyLintPass for Visibility { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + if !in_external_macro(cx.sess(), item.span) + && let VisibilityKind::Restricted { path, shorthand, .. } = &item.vis.kind + { + if **path == kw::SelfLower && let Some(false) = is_from_proc_macro(cx, item.vis.span) { + span_lint_and_sugg( + cx, + NEEDLESS_PUB_SELF, + item.vis.span, + &format!("unnecessary `pub({}self)`", if *shorthand { "" } else { "in " }), + "remove it", + String::new(), + Applicability::MachineApplicable, + ); + } + + if (**path == kw::Super || **path == kw::SelfLower || **path == kw::Crate) + && !*shorthand + && let [.., last] = &*path.segments + && let Some(false) = is_from_proc_macro(cx, item.vis.span) + { + span_lint_and_sugg( + cx, + PUB_WITHOUT_SHORTHAND, + item.vis.span, + "usage of `pub` with `in`", + "remove it", + format!("pub({})", last.ident), + Applicability::MachineApplicable, + ); + } + + if *shorthand + && let [.., last] = &*path.segments + && let Some(false) = is_from_proc_macro(cx, item.vis.span) + { + span_lint_and_sugg( + cx, + PUB_WITH_SHORTHAND, + item.vis.span, + "usage of `pub` without `in`", + "add it", + format!("pub(in {})", last.ident), + Applicability::MachineApplicable, + ); + } + } + } +} + +fn is_from_proc_macro(cx: &EarlyContext<'_>, span: Span) -> Option { + snippet_opt(cx, span).map(|s| !s.starts_with("pub")) +} diff --git a/clippy_lints/src/wildcard_imports.rs b/clippy_lints/src/wildcard_imports.rs index 36f910c983f6..1c893cafff7c 100644 --- a/clippy_lints/src/wildcard_imports.rs +++ b/clippy_lints/src/wildcard_imports.rs @@ -3,11 +3,34 @@ use clippy_utils::is_test_module_or_function; use clippy_utils::source::{snippet, snippet_with_applicability}; use if_chain::if_chain; use rustc_errors::Applicability; +<<<<<<< HEAD +<<<<<<< HEAD use rustc_hir::{ def::{DefKind, Res}, Item, ItemKind, PathSegment, UseKind, }; -use rustc_lint::{LateContext, LateLintPass}; +<<<<<<< HEAD +<<<<<<< HEAD +======= +use rustc_hir::{HirId, Mod}; +>>>>>>> 54912410c (`Wildcard_imports` ignore `test.rs` files) +======= +>>>>>>> ba0e7e88c (Now the lint ignores any crates with `--cfg test`) +======= +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{Item, ItemKind, PathSegment, UseKind}; +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{Item, ItemKind, PathSegment, UseKind}; +======= +use rustc_hir::{ + def::{DefKind, Res}, + Item, ItemKind, PathSegment, UseKind, +}; +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) +use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::kw; @@ -65,8 +88,9 @@ declare_clippy_lint! { /// This can lead to confusing error messages at best and to unexpected behavior at worst. /// /// ### Exceptions - /// Wildcard imports are allowed from modules named `prelude`. Many crates (including the standard library) - /// provide modules named "prelude" specifically designed for wildcard import. + /// Wildcard imports are allowed from modules that their name contains `prelude`. Many crates + /// (including the standard library) provide modules named "prelude" specifically designed + /// for wildcard import. /// /// `use super::*` is allowed in test modules. This is defined as any module with "test" in the name. /// @@ -117,6 +141,18 @@ impl_lint_pass!(WildcardImports => [ENUM_GLOB_USE, WILDCARD_IMPORTS]); impl LateLintPass<'_> for WildcardImports { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { +<<<<<<< HEAD +<<<<<<< HEAD + if cx.sess().is_test_crate() { +======= + if self.ignore { +>>>>>>> 54912410c (`Wildcard_imports` ignore `test.rs` files) +======= + if cx.sess().is_test_crate() { +>>>>>>> 4c3e2ff2a (Fix header) + return; + } + if is_test_module_or_function(cx.tcx, item) { self.test_modules_deep = self.test_modules_deep.saturating_add(1); } @@ -155,7 +191,7 @@ impl LateLintPass<'_> for WildcardImports { ) }; - let mut imports = used_imports.items().map(ToString::to_string).into_sorted_stable_ord(false); + let mut imports = used_imports.items().map(ToString::to_string).into_sorted_stable_ord(); let imports_string = if imports.len() == 1 { imports.pop().unwrap() } else if braced_glob { @@ -208,7 +244,9 @@ impl WildcardImports { // Allow "...prelude::..::*" imports. // Many crates have a prelude, and it is imported as a glob by design. fn is_prelude_import(segments: &[PathSegment<'_>]) -> bool { - segments.iter().any(|ps| ps.ident.name == sym::prelude) + segments + .iter() + .any(|ps| ps.ident.name.as_str().contains(sym::prelude.as_str())) } // Allow "super::*" imports in tests. diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index f194dc5d4b2e..8f1363b6074a 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -522,7 +522,7 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) { { let replacement = replacement.replace('{', "{{").replace('}', "}}"); diag.multipart_suggestion( - "try this", + "try", vec![(*placeholder_span, replacement), (removal_span, String::new())], Applicability::MachineApplicable, ); diff --git a/clippy_test_deps/Cargo.toml b/clippy_test_deps/Cargo.toml new file mode 100644 index 000000000000..4f1969606976 --- /dev/null +++ b/clippy_test_deps/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "clippy_test_deps" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +<<<<<<< HEAD +<<<<<<< HEAD +======= +clap = { version = "4.1.4", features = ["derive"] } +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) +======= +>>>>>>> 76de5560f (Add BLESS for compile-test and some cleanup) +clippy_utils = { path = "../clippy_utils" } +derive-new = "0.5" +if_chain = "1.0" +itertools = "0.10.1" +quote = "1.0" +serde = { version = "1.0.125", features = ["derive"] } +syn = { version = "2.0", features = ["full"] } +futures = "0.3" +parking_lot = "0.12" +tokio = { version = "1", features = ["io-util"] } +<<<<<<< HEAD +<<<<<<< HEAD +======= +rustc-semver = "1.1" +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) +======= +>>>>>>> 76de5560f (Add BLESS for compile-test and some cleanup) +regex = "1.5" +clippy_lints = { path = "../clippy_lints" } + +[features] +internal = ["clippy_lints/internal"] diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index 124ebd164e6b..eeedaebebb45 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -1,6 +1,10 @@ [package] name = "clippy_utils" -version = "0.1.70" +<<<<<<< HEAD +version = "0.1.73" +======= +version = "0.1.71" +>>>>>>> e4f5d83fa (Fixed formatting.) edition = "2021" publish = false diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs index 1f15598db36d..8cc01f1ef974 100644 --- a/clippy_utils/src/ast_utils.rs +++ b/clippy_utils/src/ast_utils.rs @@ -143,7 +143,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { (Paren(l), _) => eq_expr(l, r), (_, Paren(r)) => eq_expr(l, r), (Err, Err) => true, - (Try(l), Try(r)) | (Await(l), Await(r)) => eq_expr(l, r), + (Try(l), Try(r)) | (Await(l, _), Await(r, _)) => eq_expr(l, r), (Array(l), Array(r)) => over(l, r, |l, r| eq_expr(l, r)), (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)), (Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value), diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs index b4ad42a50279..51771f78d4ff 100644 --- a/clippy_utils/src/attrs.rs +++ b/clippy_utils/src/attrs.rs @@ -1,5 +1,4 @@ -use rustc_ast::ast; -use rustc_ast::attr; +use rustc_ast::{ast, attr}; use rustc_errors::Applicability; use rustc_session::Session; use rustc_span::sym; @@ -133,7 +132,7 @@ pub fn get_unique_attr<'a>( let mut unique_attr: Option<&ast::Attribute> = None; for attr in get_attr(sess, attrs, name) { if let Some(duplicate) = unique_attr { - sess.struct_span_err(attr.span, &format!("`{name}` is defined multiple times")) + sess.struct_span_err(attr.span, format!("`{name}` is defined multiple times")) .span_note(duplicate.span, "first definition found here") .emit(); } else { @@ -143,13 +142,13 @@ pub fn get_unique_attr<'a>( unique_attr } -/// Return true if the attributes contain any of `proc_macro`, +/// Returns true if the attributes contain any of `proc_macro`, /// `proc_macro_derive` or `proc_macro_attribute`, false otherwise pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool { attrs.iter().any(rustc_ast::Attribute::is_proc_macro_attr) } -/// Return true if the attributes contain `#[doc(hidden)]` +/// Returns true if the attributes contain `#[doc(hidden)]` pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool { attrs .iter() diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index d3a6929f67e2..0d11e7746b95 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -12,25 +12,33 @@ //! code was written, and check if the span contains that text. Note this will only work correctly //! if the span is not from a `macro_rules` based macro. -use rustc_ast::ast::{IntTy, LitIntType, LitKind, StrStyle, UintTy}; +use rustc_ast::ast::{AttrKind, Attribute, IntTy, LitIntType, LitKind, StrStyle, UintTy}; +use rustc_ast::token::CommentKind; +use rustc_ast::AttrStyle; +use rustc_hir::intravisit::FnKind; use rustc_hir::{ - intravisit::FnKind, Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, HirId, - Impl, ImplItem, ImplItemKind, IsAuto, Item, ItemKind, LoopSource, MatchSource, Node, QPath, TraitItem, - TraitItemKind, UnOp, UnsafeSource, Unsafety, Variant, VariantData, YieldSource, + Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, HirId, Impl, ImplItem, + ImplItemKind, IsAuto, Item, ItemKind, LoopSource, MatchSource, MutTy, Node, QPath, TraitItem, TraitItemKind, Ty, + TyKind, UnOp, UnsafeSource, Unsafety, Variant, VariantData, YieldSource, }; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; +use rustc_span::symbol::Ident; use rustc_span::{Span, Symbol}; use rustc_target::spec::abi::Abi; /// The search pattern to look for. Used by `span_matches_pat` -#[derive(Clone, Copy)] +#[derive(Clone)] pub enum Pat { /// A single string. Str(&'static str), + /// A single string. + OwnedStr(String), /// Any of the given strings. MultiStr(&'static [&'static str]), + /// Any of the given strings. + OwnedMultiStr(Vec), /// The string representation of the symbol. Sym(Symbol), /// Any decimal or hexadecimal digit depending on the location. @@ -51,12 +59,16 @@ fn span_matches_pat(sess: &Session, span: Span, start_pat: Pat, end_pat: Pat) -> let end_str = s.trim_end_matches(|c: char| c.is_whitespace() || c == ')' || c == ','); (match start_pat { Pat::Str(text) => start_str.starts_with(text), + Pat::OwnedStr(text) => start_str.starts_with(&text), Pat::MultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)), + Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)), Pat::Sym(sym) => start_str.starts_with(sym.as_str()), Pat::Num => start_str.as_bytes().first().map_or(false, u8::is_ascii_digit), } && match end_pat { Pat::Str(text) => end_str.ends_with(text), + Pat::OwnedStr(text) => end_str.starts_with(&text), Pat::MultiStr(texts) => texts.iter().any(|s| start_str.ends_with(s)), + Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)), Pat::Sym(sym) => end_str.ends_with(sym.as_str()), Pat::Num => end_str.as_bytes().last().map_or(false, u8::is_ascii_hexdigit), }) @@ -271,14 +283,149 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI (start_pat, end_pat) } +fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) { + match attr.kind { + AttrKind::Normal(..) => { +<<<<<<< HEAD +<<<<<<< HEAD + let mut pat = if matches!(attr.style, AttrStyle::Outer) { + (Pat::Str("#["), Pat::Str("]")) + } else { + (Pat::Str("#!["), Pat::Str("]")) + }; + + if let Some(ident) = attr.ident() && let Pat::Str(old_pat) = pat.0 { + // TODO: I feel like it's likely we can use `Cow` instead but this will require quite a bit of + // refactoring + // NOTE: This will likely have false positives, like `allow = 1` + pat.0 = Pat::OwnedMultiStr(vec![ident.to_string(), old_pat.to_owned()]); + pat.1 = Pat::Str(""); + } + + pat +======= + if matches!(attr.style, AttrStyle::Outer) { +======= + let mut pat = if matches!(attr.style, AttrStyle::Outer) { +>>>>>>> 497f37793 (Fix `attr_search_pat` for `#[cfg_attr]`) + (Pat::Str("#["), Pat::Str("]")) + } else { + (Pat::Str("#!["), Pat::Str("]")) + }; + + if let Some(ident) = attr.ident() && let Pat::Str(old_pat) = pat.0 { + // TODO: I feel like it's likely we can use `Cow` instead but this will require quite a bit of + // refactoring + // NOTE: This will likely have false positives, like `allow = 1` + pat.0 = Pat::OwnedMultiStr(vec![ident.to_string(), old_pat.to_owned()]); + pat.1 = Pat::Str(""); + } +<<<<<<< HEAD +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= + + pat +>>>>>>> 497f37793 (Fix `attr_search_pat` for `#[cfg_attr]`) + }, + AttrKind::DocComment(_kind @ CommentKind::Line, ..) => { + if matches!(attr.style, AttrStyle::Outer) { + (Pat::Str("///"), Pat::Str("")) + } else { + (Pat::Str("//!"), Pat::Str("")) + } + }, + AttrKind::DocComment(_kind @ CommentKind::Block, ..) => { + if matches!(attr.style, AttrStyle::Outer) { + (Pat::Str("/**"), Pat::Str("*/")) + } else { + (Pat::Str("/*!"), Pat::Str("*/")) + } + }, + } +} + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +// TODO: Waiting on `ty_search_pat`. +// fn where_pred_search_pat(where_pred: &WherePredicate<'_>) -> (Pat, Pat) { +// match where_pred { +// WherePredicate::BoundPredicate(bound) => { +// todo!(); +// }, +// WherePredicate::RegionPredicate(region) => { +// +// }, +// WherePredicate::EqPredicate(..) => unimplemented!(), +// } +// } + +>>>>>>> e97f190a9 (`ty_search_pat`) +======= +>>>>>>> 4191de330 (Update check_proc_macro.rs) +fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) { + match ty.kind { + TyKind::Slice(..) | TyKind::Array(..) => (Pat::Str("["), Pat::Str("]")), + TyKind::Ptr(MutTy { mutbl, ty }) => ( + if mutbl.is_mut() { + Pat::Str("*const") + } else { + Pat::Str("*mut") + }, + ty_search_pat(ty).1, + ), + TyKind::Ref(_, MutTy { ty, .. }) => (Pat::Str("&"), ty_search_pat(ty).1), + TyKind::BareFn(bare_fn) => ( + Pat::OwnedStr(format!("{}{} fn", bare_fn.unsafety.prefix_str(), bare_fn.abi.name())), + ty_search_pat(ty).1, + ), + TyKind::Never => (Pat::Str("!"), Pat::Str("")), + TyKind::Tup(..) => (Pat::Str("("), Pat::Str(")")), + TyKind::OpaqueDef(..) => (Pat::Str("impl"), Pat::Str("")), +<<<<<<< HEAD +<<<<<<< HEAD + TyKind::Path(qpath) => qpath_search_pat(&qpath), +<<<<<<< HEAD + // NOTE: This is missing `TraitObject`. It always return true then. +======= + // NOTE: This is missing `TraitObject` and `Path` here. It always return true then. +>>>>>>> e97f190a9 (`ty_search_pat`) +======= + TyKind::Path(qpath) => qpath_search_pat(&qpath), + // NOTE: This is missing `TraitObject`. It always return true then. +>>>>>>> a434a7715 (`impl WithSearchPat for Ty`) +======= + // NOTE: This is missing `TraitObject`. It will always return true then. +>>>>>>> 885a18207 (Fix typos) + _ => (Pat::Str(""), Pat::Str("")), + } +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 52cfc997a (Add lint `single_letter_idents`) +fn ident_search_pat(ident: Ident) -> (Pat, Pat) { + (Pat::OwnedStr(ident.name.as_str().to_owned()), Pat::Str("")) +} + +pub trait WithSearchPat<'cx> { +<<<<<<< HEAD +======= +======= +>>>>>>> e97f190a9 (`ty_search_pat`) pub trait WithSearchPat { +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= +>>>>>>> 52cfc997a (Add lint `single_letter_idents`) type Context: LintContext; fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat); fn span(&self) -> Span; } macro_rules! impl_with_search_pat { ($cx:ident: $ty:ident with $fn:ident $(($tcx:ident))?) => { - impl<'cx> WithSearchPat for $ty<'cx> { + impl<'cx> WithSearchPat<'cx> for $ty<'cx> { type Context = $cx<'cx>; #[allow(unused_variables)] fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat) { @@ -297,8 +444,9 @@ impl_with_search_pat!(LateContext: TraitItem with trait_item_search_pat); impl_with_search_pat!(LateContext: ImplItem with impl_item_search_pat); impl_with_search_pat!(LateContext: FieldDef with field_def_search_pat); impl_with_search_pat!(LateContext: Variant with variant_search_pat); +impl_with_search_pat!(LateContext: Ty with ty_search_pat); -impl<'cx> WithSearchPat for (&FnKind<'cx>, &Body<'cx>, HirId, Span) { +impl<'cx> WithSearchPat<'cx> for (&FnKind<'cx>, &Body<'cx>, HirId, Span) { type Context = LateContext<'cx>; fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat) { @@ -310,11 +458,61 @@ impl<'cx> WithSearchPat for (&FnKind<'cx>, &Body<'cx>, HirId, Span) { } } +<<<<<<< HEAD +<<<<<<< HEAD +// `Attribute` does not have the `hir` associated lifetime, so we cannot use the macro +impl<'cx> WithSearchPat<'cx> for &'cx Attribute { + type Context = LateContext<'cx>; + + fn search_pat(&self, _cx: &Self::Context) -> (Pat, Pat) { + attr_search_pat(self) + } + + fn span(&self) -> Span { + self.span + } +} + +// `Ident` does not have the `hir` associated lifetime, so we cannot use the macro +impl<'cx> WithSearchPat<'cx> for Ident { + type Context = LateContext<'cx>; + + fn search_pat(&self, _cx: &Self::Context) -> (Pat, Pat) { + ident_search_pat(*self) + } + + fn span(&self) -> Span { + self.span +<<<<<<< HEAD +======= +impl<'cx> WithSearchPat for (&Attribute, &LateContext<'cx>) { +======= +// `Attribute` does not have the `hir` associated lifetime, so we cannot use the macro +impl<'cx> WithSearchPat for &'cx Attribute { +>>>>>>> 05bfcbd91 (remove tuple) + type Context = LateContext<'cx>; + + fn search_pat(&self, _cx: &Self::Context) -> (Pat, Pat) { + attr_search_pat(self) + } + + fn span(&self) -> Span { +<<<<<<< HEAD + self.0.span +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= + self.span +>>>>>>> 05bfcbd91 (remove tuple) +======= +>>>>>>> 52cfc997a (Add lint `single_letter_idents`) + } +} + /// Checks if the item likely came from a proc-macro. /// /// This should be called after `in_external_macro` and the initial pattern matching of the ast as /// it is significantly slower than both of those. -pub fn is_from_proc_macro(cx: &T::Context, item: &T) -> bool { +pub fn is_from_proc_macro<'cx, T: WithSearchPat<'cx>>(cx: &T::Context, item: &T) -> bool { let (start_pat, end_pat) = item.search_pat(cx); !span_matches_pat(cx.sess(), item.span(), start_pat, end_pat) } diff --git a/clippy_utils/src/comparisons.rs b/clippy_utils/src/comparisons.rs index 7a18d5e818fb..5e6bf2278442 100644 --- a/clippy_utils/src/comparisons.rs +++ b/clippy_utils/src/comparisons.rs @@ -1,11 +1,11 @@ -//! Utility functions about comparison operators. +//! Utility functions for comparison operators. #![deny(clippy::missing_docs_in_private_items)] use rustc_hir::{BinOpKind, Expr}; #[derive(PartialEq, Eq, Debug, Copy, Clone)] -/// Represent a normalized comparison operator. +/// Represents a normalized comparison operator. pub enum Rel { /// `<` Lt, diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index bb8890dcaf98..de5fc5fd2655 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -1,25 +1,57 @@ #![allow(clippy::float_cmp)] +<<<<<<< HEAD +<<<<<<< HEAD +use crate::source::{get_source_text, walk_span_to_context}; +======= +use crate::source::{span_source_range, walk_span_to_context}; +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) +======= +use crate::source::{get_source_text, walk_span_to_context}; +>>>>>>> 58132cb3b (Improve `SpanlessEq`) use crate::{clip, is_direct_expn_of, sext, unsext}; use if_chain::if_chain; use rustc_ast::ast::{self, LitFloatType, LitKind}; use rustc_data_structures::sync::Lrc; use rustc_hir::def::{DefKind, Res}; +<<<<<<< HEAD +<<<<<<< HEAD +use rustc_hir::{BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp}; +======= use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp}; +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) +======= +use rustc_hir::{AnonConst, BinOp, BinOpKind, Block, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp}; +>>>>>>> 6a1084c26 (Check if `if` conditions always evaluate to true in `never_loop`) +use rustc_lexer::tokenize; use rustc_lint::LateContext; -use rustc_middle::mir; use rustc_middle::mir::interpret::Scalar; -use rustc_middle::ty::SubstsRef; +<<<<<<< HEAD use rustc_middle::ty::{self, EarlyBinder, FloatTy, ScalarInt, Ty, TyCtxt}; +use rustc_middle::ty::{List, SubstsRef}; use rustc_middle::{bug, span_bug}; +<<<<<<< HEAD +<<<<<<< HEAD +======= +use rustc_middle::ty::{self, EarlyBinder, FloatTy, List, ScalarInt, SubstsRef, Ty, TyCtxt}; +use rustc_middle::{bug, mir, span_bug}; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) +use rustc_span::symbol::{Ident, Symbol}; +======= use rustc_span::symbol::Symbol; +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) +======= +use rustc_span::symbol::{Ident, Symbol}; +>>>>>>> 0e1caa765 (Fix #10792) +use rustc_span::SyntaxContext; use std::cmp::Ordering::{self, Equal}; use std::hash::{Hash, Hasher}; use std::iter; /// A `LitKind`-like enum to fold constant `Expr`s into. #[derive(Debug, Clone)] -pub enum Constant { +pub enum Constant<'tcx> { + Adt(rustc_middle::mir::ConstantKind<'tcx>), /// A `String` (e.g., "abc"). Str(String), /// A binary string (e.g., `b"abc"`). @@ -35,20 +67,20 @@ pub enum Constant { /// `true` or `false`. Bool(bool), /// An array of constants. - Vec(Vec), + Vec(Vec>), /// Also an array, but with only one constant, repeated N times. - Repeat(Box, u64), + Repeat(Box>, u64), /// A tuple of constants. - Tuple(Vec), + Tuple(Vec>), /// A raw pointer. RawPtr(u128), /// A reference - Ref(Box), + Ref(Box>), /// A literal with syntax error. Err, } -impl PartialEq for Constant { +impl<'tcx> PartialEq for Constant<'tcx> { fn eq(&self, other: &Self) -> bool { match (self, other) { (Self::Str(ls), Self::Str(rs)) => ls == rs, @@ -77,13 +109,16 @@ impl PartialEq for Constant { } } -impl Hash for Constant { +impl<'tcx> Hash for Constant<'tcx> { fn hash(&self, state: &mut H) where H: Hasher, { std::mem::discriminant(self).hash(state); match *self { + Self::Adt(ref elem) => { + elem.hash(state); + }, Self::Str(ref s) => { s.hash(state); }, @@ -123,7 +158,7 @@ impl Hash for Constant { } } -impl Constant { +impl<'tcx> Constant<'tcx> { pub fn partial_cmp(tcx: TyCtxt<'_>, cmp_type: Ty<'_>, left: &Self, right: &Self) -> Option { match (left, right) { (Self::Str(ls), Self::Str(rs)) => Some(ls.cmp(rs)), @@ -206,11 +241,11 @@ impl Constant { } /// Parses a `LitKind` to a `Constant`. -pub fn lit_to_mir_constant(lit: &LitKind, ty: Option>) -> Constant { +pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option>) -> Constant<'tcx> { match *lit { LitKind::Str(ref is, _) => Constant::Str(is.to_string()), LitKind::Byte(b) => Constant::Int(u128::from(b)), - LitKind::ByteStr(ref s, _) => Constant::Binary(Lrc::clone(s)), + LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(Lrc::clone(s)), LitKind::Char(c) => Constant::Char(c), LitKind::Int(n, _) => Constant::Int(n), LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty { @@ -227,27 +262,70 @@ pub fn lit_to_mir_constant(lit: &LitKind, ty: Option>) -> Constant { } } +/// The source of a constant value. +pub enum ConstantSource { + /// The value is determined solely from the expression. + Local, + /// The value is dependent on a defined constant. + Constant, +} +impl ConstantSource { + pub fn is_local(&self) -> bool { + matches!(self, Self::Local) + } +} + +/// Attempts to evaluate the expression as a constant. pub fn constant<'tcx>( lcx: &LateContext<'tcx>, typeck_results: &ty::TypeckResults<'tcx>, e: &Expr<'_>, -) -> Option<(Constant, bool)> { - let mut cx = ConstEvalLateContext { - lcx, - typeck_results, - param_env: lcx.param_env, - needed_resolution: false, - substs: ty::List::empty(), - }; - cx.expr(e).map(|cst| (cst, cx.needed_resolution)) +<<<<<<< HEAD +<<<<<<< HEAD +) -> Option> { +======= +) -> Option { +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) +======= +) -> Option> { +>>>>>>> 0e1caa765 (Fix #10792) + ConstEvalLateContext::new(lcx, typeck_results).expr(e) +} + +/// Attempts to evaluate the expression as a constant. +pub fn constant_with_source<'tcx>( + lcx: &LateContext<'tcx>, + typeck_results: &ty::TypeckResults<'tcx>, + e: &Expr<'_>, +<<<<<<< HEAD +<<<<<<< HEAD +) -> Option<(Constant<'tcx>, ConstantSource)> { +======= +) -> Option<(Constant, ConstantSource)> { +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) +======= +) -> Option<(Constant<'tcx>, ConstantSource)> { +>>>>>>> 0e1caa765 (Fix #10792) + let mut ctxt = ConstEvalLateContext::new(lcx, typeck_results); + let res = ctxt.expr(e); + res.map(|x| (x, ctxt.source)) } +/// Attempts to evaluate an expression only if its value is not dependent on other items. pub fn constant_simple<'tcx>( lcx: &LateContext<'tcx>, typeck_results: &ty::TypeckResults<'tcx>, e: &Expr<'_>, +<<<<<<< HEAD +<<<<<<< HEAD +) -> Option> { +======= ) -> Option { - constant(lcx, typeck_results, e).and_then(|(cst, res)| if res { None } else { Some(cst) }) +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) +======= +) -> Option> { +>>>>>>> 0e1caa765 (Fix #10792) + constant_with_source(lcx, typeck_results, e).and_then(|(c, s)| s.is_local().then_some(c)) } pub fn constant_full_int<'tcx>( @@ -296,32 +374,34 @@ impl Ord for FullInt { } } -/// Creates a `ConstEvalLateContext` from the given `LateContext` and `TypeckResults`. -pub fn constant_context<'a, 'tcx>( - lcx: &'a LateContext<'tcx>, - typeck_results: &'a ty::TypeckResults<'tcx>, -) -> ConstEvalLateContext<'a, 'tcx> { - ConstEvalLateContext { - lcx, - typeck_results, - param_env: lcx.param_env, - needed_resolution: false, - substs: ty::List::empty(), - } -} - pub struct ConstEvalLateContext<'a, 'tcx> { lcx: &'a LateContext<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>, param_env: ty::ParamEnv<'tcx>, - needed_resolution: bool, + source: ConstantSource, substs: SubstsRef<'tcx>, } impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { + fn new(lcx: &'a LateContext<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>) -> Self { + Self { + lcx, + typeck_results, + param_env: lcx.param_env, + source: ConstantSource::Local, + substs: List::empty(), + } + } + /// Simple constant folding: Insert an expression, get a constant or none. - pub fn expr(&mut self, e: &Expr<'_>) -> Option { + pub fn expr(&mut self, e: &Expr<'_>) -> Option> { match e.kind { +<<<<<<< HEAD + ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.lcx.tcx.hir().body(body).value), +======= + ExprKind::ConstBlock(AnonConst { body, .. }) => self.expr(self.lcx.tcx.hir().body(body).value), +>>>>>>> 6a1084c26 (Check if `if` conditions always evaluate to true in `never_loop`) + ExprKind::DropTemps(e) => self.expr(e), ExprKind::Path(ref qpath) => self.fetch_path(qpath, e.hir_id, self.typeck_results.expr_ty(e)), ExprKind::Block(block, _) => self.block(block), ExprKind::Lit(ref lit) => { @@ -374,13 +454,33 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { }, ExprKind::Index(arr, index) => self.index(arr, index), ExprKind::AddrOf(_, _, inner) => self.expr(inner).map(|r| Constant::Ref(Box::new(r))), - // TODO: add other expressions. +<<<<<<< HEAD +<<<<<<< HEAD + ExprKind::Field(local_expr, ref field) => { +======= + ExprKind::Field(ref local_expr, ref field) => { +>>>>>>> 0e1caa765 (Fix #10792) +======= + ExprKind::Field(local_expr, ref field) => { +>>>>>>> dbe405723 (Dogfood) + let result = self.expr(local_expr); + if let Some(Constant::Adt(constant)) = &self.expr(local_expr) + && let ty::Adt(adt_def, _) = constant.ty().kind() + && adt_def.is_struct() + && let Some(desired_field) = field_of_struct(*adt_def, self.lcx, *constant, field) + { + miri_to_const(self.lcx, desired_field) + } + else { + result + } + }, _ => None, } } #[expect(clippy::cast_possible_wrap)] - fn constant_not(&self, o: &Constant, ty: Ty<'_>) -> Option { + fn constant_not(&self, o: &Constant<'tcx>, ty: Ty<'_>) -> Option> { use self::Constant::{Bool, Int}; match *o { Bool(b) => Some(Bool(!b)), @@ -396,7 +496,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { } } - fn constant_negate(&self, o: &Constant, ty: Ty<'_>) -> Option { + fn constant_negate(&self, o: &Constant<'tcx>, ty: Ty<'_>) -> Option> { use self::Constant::{Int, F32, F64}; match *o { Int(value) => { @@ -415,28 +515,25 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { /// Create `Some(Vec![..])` of all constants, unless there is any /// non-constant part. - fn multi(&mut self, vec: &[Expr<'_>]) -> Option> { + fn multi(&mut self, vec: &[Expr<'_>]) -> Option>> { vec.iter().map(|elem| self.expr(elem)).collect::>() } /// Lookup a possibly constant expression from an `ExprKind::Path`. - fn fetch_path(&mut self, qpath: &QPath<'_>, id: HirId, ty: Ty<'tcx>) -> Option { + fn fetch_path(&mut self, qpath: &QPath<'_>, id: HirId, ty: Ty<'tcx>) -> Option> { let res = self.typeck_results.qpath_res(qpath, id); match res { Res::Def(DefKind::Const | DefKind::AssocConst, def_id) => { // Check if this constant is based on `cfg!(..)`, // which is NOT constant for our purposes. - if let Some(node) = self.lcx.tcx.hir().get_if_local(def_id) && - let Node::Item(&Item { - kind: ItemKind::Const(_, body_id), - .. - }) = node && - let Node::Expr(&Expr { - kind: ExprKind::Lit(_), - span, - .. - }) = self.lcx.tcx.hir().get(body_id.hir_id) && - is_direct_expn_of(span, "cfg").is_some() { + if let Some(node) = self.lcx.tcx.hir().get_if_local(def_id) + && let Node::Item(Item { kind: ItemKind::Const(_, body_id), .. }) = node + && let Node::Expr(Expr { kind: ExprKind::Lit(_), span, .. }) = self.lcx + .tcx + .hir() + .get(body_id.hir_id) + && is_direct_expn_of(*span, "cfg").is_some() + { return None; } @@ -444,31 +541,31 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { let substs = if self.substs.is_empty() { substs } else { - EarlyBinder(substs).subst(self.lcx.tcx, self.substs) + EarlyBinder::bind(substs).subst(self.lcx.tcx, self.substs) }; - let result = self .lcx .tcx - .const_eval_resolve( - self.param_env, - mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs), - None, - ) + .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, substs), None) .ok() .map(|val| rustc_middle::mir::ConstantKind::from_value(val, ty))?; - let result = miri_to_const(self.lcx.tcx, result); - if result.is_some() { - self.needed_resolution = true; - } - result +<<<<<<< HEAD +<<<<<<< HEAD + let result = miri_to_const(self.lcx, result)?; +======= + let result = miri_to_const(self.lcx.tcx, result)?; +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) +======= + let result = miri_to_const(self.lcx, result)?; +>>>>>>> 0e1caa765 (Fix #10792) + self.source = ConstantSource::Constant; + Some(result) }, - // FIXME: cover all usable cases. _ => None, } } - fn index(&mut self, lhs: &'_ Expr<'_>, index: &'_ Expr<'_>) -> Option { + fn index(&mut self, lhs: &'_ Expr<'_>, index: &'_ Expr<'_>) -> Option> { let lhs = self.expr(lhs); let index = self.expr(index); @@ -494,15 +591,56 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { } /// A block can only yield a constant if it only has one constant expression. +<<<<<<< HEAD +<<<<<<< HEAD + fn block(&mut self, block: &Block<'_>) -> Option> { +======= fn block(&mut self, block: &Block<'_>) -> Option { - if block.stmts.is_empty() { - block.expr.as_ref().and_then(|b| self.expr(b)) +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) +======= + fn block(&mut self, block: &Block<'_>) -> Option> { +>>>>>>> 0e1caa765 (Fix #10792) + if block.stmts.is_empty() + && let Some(expr) = block.expr + { + // Try to detect any `cfg`ed statements or empty macro expansions. + let span = block.span.data(); + if span.ctxt == SyntaxContext::root() { + if let Some(expr_span) = walk_span_to_context(expr.span, span.ctxt) + && let expr_lo = expr_span.lo() + && expr_lo >= span.lo +<<<<<<< HEAD +<<<<<<< HEAD + && let Some(src) = get_source_text(self.lcx, span.lo..expr_lo) +======= + && let Some(src) = span_source_range(self.lcx, span.lo..expr_lo) +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) +======= + && let Some(src) = get_source_text(self.lcx, span.lo..expr_lo) +>>>>>>> 58132cb3b (Improve `SpanlessEq`) + && let Some(src) = src.as_str() + { + use rustc_lexer::TokenKind::{Whitespace, LineComment, BlockComment, Semi, OpenBrace}; + if !tokenize(src) + .map(|t| t.kind) + .filter(|t| !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi)) + .eq([OpenBrace]) + { + self.source = ConstantSource::Constant; + } + } else { + // Unable to access the source. Assume a non-local dependency. + self.source = ConstantSource::Constant; + } + } + + self.expr(expr) } else { None } } - fn ifthenelse(&mut self, cond: &Expr<'_>, then: &Expr<'_>, otherwise: Option<&Expr<'_>>) -> Option { + fn ifthenelse(&mut self, cond: &Expr<'_>, then: &Expr<'_>, otherwise: Option<&Expr<'_>>) -> Option> { if let Some(Constant::Bool(b)) = self.expr(cond) { if b { self.expr(then) @@ -514,7 +652,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { } } - fn binop(&mut self, op: BinOp, left: &Expr<'_>, right: &Expr<'_>) -> Option { + fn binop(&mut self, op: BinOp, left: &Expr<'_>, right: &Expr<'_>) -> Option> { let l = self.expr(left)?; let r = self.expr(right); match (l, r) { @@ -607,23 +745,21 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { } } -pub fn miri_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: mir::ConstantKind<'tcx>) -> Option { +pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::ConstantKind<'tcx>) -> Option> { use rustc_middle::mir::interpret::ConstValue; match result { - mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(int)), _) => { - match result.ty().kind() { - ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)), - ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.assert_bits(int.size()))), - ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits( - int.try_into().expect("invalid f32 bit representation"), - ))), - ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits( - int.try_into().expect("invalid f64 bit representation"), - ))), - ty::RawPtr(_) => Some(Constant::RawPtr(int.assert_bits(int.size()))), - // FIXME: implement other conversions. - _ => None, - } + mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() { + ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)), + ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)), + ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.assert_bits(int.size()))), + ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits( + int.try_into().expect("invalid f32 bit representation"), + ))), + ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits( + int.try_into().expect("invalid f64 bit representation"), + ))), + ty::RawPtr(_) => Some(Constant::RawPtr(int.assert_bits(int.size()))), + _ => None, }, mir::ConstantKind::Val(ConstValue::Slice { data, start, end }, _) => match result.ty().kind() { ty::Ref(_, tam, _) => match tam.kind() { @@ -639,35 +775,72 @@ pub fn miri_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: mir::ConstantKind<'tcx>) - _ => None, }, mir::ConstantKind::Val(ConstValue::ByRef { alloc, offset: _ }, _) => match result.ty().kind() { + ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)), ty::Array(sub_type, len) => match sub_type.kind() { - ty::Float(FloatTy::F32) => match len.kind().try_to_target_usize(tcx) { +<<<<<<< HEAD + ty::Float(FloatTy::F32) => match len.try_to_target_usize(lcx.tcx) { +======= + ty::Float(FloatTy::F32) => match len.kind().try_to_target_usize(lcx.tcx) { +>>>>>>> 0e1caa765 (Fix #10792) Some(len) => alloc .inner() .inspect_with_uninit_and_ptr_outside_interpreter(0..(4 * usize::try_from(len).unwrap())) .to_owned() .array_chunks::<4>() .map(|&chunk| Some(Constant::F32(f32::from_le_bytes(chunk)))) - .collect::>>() + .collect::>>>() .map(Constant::Vec), _ => None, }, - ty::Float(FloatTy::F64) => match len.kind().try_to_target_usize(tcx) { +<<<<<<< HEAD + ty::Float(FloatTy::F64) => match len.try_to_target_usize(lcx.tcx) { +======= + ty::Float(FloatTy::F64) => match len.kind().try_to_target_usize(lcx.tcx) { +>>>>>>> 0e1caa765 (Fix #10792) Some(len) => alloc .inner() .inspect_with_uninit_and_ptr_outside_interpreter(0..(8 * usize::try_from(len).unwrap())) .to_owned() .array_chunks::<8>() .map(|&chunk| Some(Constant::F64(f64::from_le_bytes(chunk)))) - .collect::>>() + .collect::>>>() .map(Constant::Vec), _ => None, }, - // FIXME: implement other array type conversions. _ => None, }, _ => None, }, - // FIXME: implement other conversions. _ => None, } } + +fn field_of_struct<'tcx>( + adt_def: ty::AdtDef<'tcx>, + lcx: &LateContext<'tcx>, + result: mir::ConstantKind<'tcx>, + field: &Ident, +) -> Option> { +<<<<<<< HEAD + if let mir::ConstantKind::Val(result, ty) = result + && let Some(dc) = lcx.tcx.try_destructure_mir_constant_for_diagnostics((result, ty)) + && let Some(dc_variant) = dc.variant + && let Some(variant) = adt_def.variants().get(dc_variant) + && let Some(field_idx) = variant.fields.iter().position(|el| el.name == field.name) + && let Some(&(val, ty)) = dc.fields.get(field_idx) + { + Some(mir::ConstantKind::Val(val, ty)) +======= + let dc = lcx.tcx.destructure_mir_constant(lcx.param_env, result); + if let Some(dc_variant) = dc.variant + && let Some(variant) = adt_def.variants().get(dc_variant) + && let Some(field_idx) = variant.fields.iter().position(|el| el.name == field.name) + && let Some(dc_field) = dc.fields.get(field_idx) + { + Some(*dc_field) +>>>>>>> 0e1caa765 (Fix #10792) + } + else { + None + } +} diff --git a/clippy_utils/src/diagnostics.rs b/clippy_utils/src/diagnostics.rs index 812f6fe71a0a..edd87546a5f8 100644 --- a/clippy_utils/src/diagnostics.rs +++ b/clippy_utils/src/diagnostics.rs @@ -46,7 +46,7 @@ fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) { /// | ^^^^^^^^^^^^^^^^^^^^^^^ /// ``` pub fn span_lint(cx: &T, lint: &'static Lint, sp: impl Into, msg: &str) { - cx.struct_span_lint(lint, sp, msg, |diag| { + cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { docs_link(diag, lint); diag }); @@ -80,11 +80,12 @@ pub fn span_lint_and_help( help_span: Option, help: &str, ) { - cx.struct_span_lint(lint, span, msg, |diag| { + cx.struct_span_lint(lint, span, msg.to_string(), |diag| { + let help = help.to_string(); if let Some(help_span) = help_span { - diag.span_help(help_span, help); + diag.span_help(help_span, help.to_string()); } else { - diag.help(help); + diag.help(help.to_string()); } docs_link(diag, lint); diag @@ -122,7 +123,8 @@ pub fn span_lint_and_note( note_span: Option, note: &str, ) { - cx.struct_span_lint(lint, span, msg, |diag| { + cx.struct_span_lint(lint, span, msg.to_string(), |diag| { + let note = note.to_string(); if let Some(note_span) = note_span { diag.span_note(note_span, note); } else { @@ -143,7 +145,7 @@ where S: Into, F: FnOnce(&mut Diagnostic), { - cx.struct_span_lint(lint, sp, msg, |diag| { + cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); diag @@ -151,7 +153,7 @@ where } pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) { - cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg, |diag| { + cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { docs_link(diag, lint); diag }); @@ -165,7 +167,7 @@ pub fn span_lint_hir_and_then( msg: &str, f: impl FnOnce(&mut Diagnostic), ) { - cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg, |diag| { + cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); diag @@ -202,7 +204,7 @@ pub fn span_lint_and_sugg( applicability: Applicability, ) { span_lint_and_then(cx, lint, sp, msg, |diag| { - diag.span_suggestion(sp, help, sugg, applicability); + diag.span_suggestion(sp, help.to_string(), sugg, applicability); }); } @@ -232,5 +234,5 @@ pub fn multispan_sugg_with_applicability( ) where I: IntoIterator, { - diag.multipart_suggestion(help_msg, sugg.into_iter().collect(), applicability); + diag.multipart_suggestion(help_msg.to_string(), sugg.into_iter().collect(), applicability); } diff --git a/clippy_utils/src/eager_or_lazy.rs b/clippy_utils/src/eager_or_lazy.rs index 28c857170613..e16a18e1a105 100644 --- a/clippy_utils/src/eager_or_lazy.rs +++ b/clippy_utils/src/eager_or_lazy.rs @@ -1,7 +1,7 @@ //! Utilities for evaluating whether eagerly evaluated expressions can be made lazy and vice versa. //! //! Things to consider: -//! - has the expression side-effects? +//! - does the expression have side-effects? //! - is the expression computationally expensive? //! //! See lints: @@ -12,13 +12,19 @@ use crate::ty::{all_predicates_of, is_copy}; use crate::visitors::is_const_evaluatable; use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_expr, Visitor}; -use rustc_hir::{def_id::DefId, Block, Expr, ExprKind, QPath, UnOp}; +use rustc_hir::{Block, Expr, ExprKind, QPath, UnOp}; use rustc_lint::LateContext; +<<<<<<< HEAD +use rustc_middle::ty; +use rustc_middle::ty::adjustment::Adjust; +======= +use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::{self, PredicateKind}; +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) use rustc_span::{sym, Symbol}; -use std::cmp; -use std::ops; +use std::{cmp, ops}; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] enum EagernessSuggestion { @@ -73,7 +79,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: .flat_map(|v| v.fields.iter()) .any(|x| matches!(cx.tcx.type_of(x.did).subst_identity().peel_refs().kind(), ty::Param(_))) && all_predicates_of(cx.tcx, fn_id).all(|(pred, _)| match pred.kind().skip_binder() { - PredicateKind::Clause(ty::Clause::Trait(pred)) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker, + ty::ClauseKind::Trait(pred) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker, _ => true, }) && subs.types().all(|x| matches!(x.peel_refs().kind(), ty::Param(_))) @@ -114,6 +120,20 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS if self.eagerness == ForceNoChange { return; } + + // Autoderef through a user-defined `Deref` impl can have side-effects, + // so don't suggest changing it. + if self + .cx + .typeck_results() + .expr_adjustments(e) + .iter() + .any(|adj| matches!(adj.kind, Adjust::Deref(Some(_)))) + { + self.eagerness |= NoChange; + return; + } + match e.kind { ExprKind::Call( &Expr { @@ -173,11 +193,15 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS self.eagerness = Lazy; } }, - + // Custom `Deref` impl might have side effects + ExprKind::Unary(UnOp::Deref, e) + if self.cx.typeck_results().expr_ty(e).builtin_deref(true).is_none() => + { + self.eagerness |= NoChange; + }, // Dereferences should be cheap, but dereferencing a raw pointer earlier may not be safe. ExprKind::Unary(UnOp::Deref, e) if !self.cx.typeck_results().expr_ty(e).is_unsafe_ptr() => (), ExprKind::Unary(UnOp::Deref, _) => self.eagerness |= NoChange, - ExprKind::Unary(_, e) if matches!( self.cx.typeck_results().expr_ty(e).kind(), @@ -191,6 +215,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS ExprKind::Break(..) | ExprKind::Continue(_) | ExprKind::Ret(_) + | ExprKind::Become(_) | ExprKind::InlineAsm(_) | ExprKind::Yield(..) | ExprKind::Err(_) => { @@ -218,7 +243,8 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS | ExprKind::AddrOf(..) | ExprKind::Struct(..) | ExprKind::Repeat(..) - | ExprKind::Block(Block { stmts: [], .. }, _) => (), + | ExprKind::Block(Block { stmts: [], .. }, _) + | ExprKind::OffsetOf(..) => (), // Assignment might be to a local defined earlier, so don't eagerly evaluate. // Blocks with multiple statements might be expensive, so don't eagerly evaluate. diff --git a/clippy_utils/src/higher.rs b/clippy_utils/src/higher.rs index 50bef3709309..357ac40b4559 100644 --- a/clippy_utils/src/higher.rs +++ b/clippy_utils/src/higher.rs @@ -13,7 +13,7 @@ use rustc_lint::LateContext; use rustc_span::{sym, symbol, Span}; /// The essential nodes of a desugared for loop as well as the entire span: -/// `for pat in arg { body }` becomes `(pat, arg, body)`. Return `(pat, arg, body, span)`. +/// `for pat in arg { body }` becomes `(pat, arg, body)`. Returns `(pat, arg, body, span)`. pub struct ForLoop<'tcx> { /// `for` loop item pub pat: &'tcx hir::Pat<'tcx>, @@ -264,7 +264,7 @@ impl<'a> Range<'a> { } } -/// Represent the pre-expansion arguments of a `vec!` invocation. +/// Represents the pre-expansion arguments of a `vec!` invocation. pub enum VecArgs<'a> { /// `vec![elem; len]` Repeat(&'a hir::Expr<'a>, &'a hir::Expr<'a>), @@ -311,6 +311,8 @@ pub struct While<'hir> { pub condition: &'hir Expr<'hir>, /// `while` loop body pub body: &'hir Expr<'hir>, + /// Span of the loop header + pub span: Span, } impl<'hir> While<'hir> { @@ -336,10 +338,10 @@ impl<'hir> While<'hir> { }, _, LoopSource::While, - _, + span, ) = expr.kind { - return Some(Self { condition, body }); + return Some(Self { condition, body, span }); } None } @@ -396,7 +398,7 @@ impl<'hir> WhileLet<'hir> { } } -/// Converts a hir binary operator to the corresponding `ast` type. +/// Converts a `hir` binary operator to the corresponding `ast` type. #[must_use] pub fn binop(op: hir::BinOpKind) -> ast::BinOpKind { match op { @@ -434,7 +436,7 @@ pub enum VecInitKind { WithExprCapacity(HirId), } -/// Checks if given expression is an initialization of `Vec` and returns its kind. +/// Checks if the given expression is an initialization of `Vec` and returns its kind. pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option { if let ExprKind::Call(func, args) = expr.kind { match func.kind { diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 3ee7147828bd..db99ddf551d5 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -1,20 +1,29 @@ use crate::consts::constant_simple; use crate::macros::macro_backtrace; -use crate::source::snippet_opt; +use crate::source::{get_source_text, snippet_opt, walk_span_to_context, SpanRange}; +use crate::tokenize_with_text; use rustc_ast::ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxHasher; use rustc_hir::def::Res; -use rustc_hir::HirIdMap; use rustc_hir::{ ArrayLen, BinOpKind, BindingAnnotation, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg, - GenericArgs, Guard, HirId, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path, + GenericArgs, Guard, HirId, HirIdMap, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding, }; use rustc_lexer::{tokenize, TokenKind}; use rustc_lint::LateContext; use rustc_middle::ty::TypeckResults; -use rustc_span::{sym, Symbol}; +<<<<<<< HEAD +<<<<<<< HEAD +use rustc_span::{sym, BytePos, ExpnKind, MacroKind, Symbol, SyntaxContext}; +======= +use rustc_span::{sym, BytePos, Symbol, SyntaxContext}; +>>>>>>> 0b3c2ed81 (Search for inactive `cfg` attributes and empty macro expansion through) +======= +use rustc_span::{sym, BytePos, ExpnKind, MacroKind, Symbol, SyntaxContext}; +>>>>>>> 58132cb3b (Improve `SpanlessEq`) use std::hash::{Hash, Hasher}; +use std::ops::Range; /// Callback that is called when two expressions are not equal in the sense of `SpanlessEq`, but /// other conditions would make them equal. @@ -65,6 +74,8 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { pub fn inter_expr(&mut self) -> HirEqInterExpr<'_, 'a, 'tcx> { HirEqInterExpr { inner: self, + left_ctxt: SyntaxContext::root(), + right_ctxt: SyntaxContext::root(), locals: HirIdMap::default(), } } @@ -92,6 +103,8 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { pub struct HirEqInterExpr<'a, 'b, 'tcx> { inner: &'a mut SpanlessEq<'b, 'tcx>, + left_ctxt: SyntaxContext, + right_ctxt: SyntaxContext, // When binding are declared, the binding ID in the left expression is mapped to the one on the // right. For example, when comparing `{ let x = 1; x + 2 }` and `{ let y = 1; y + 2 }`, @@ -126,52 +139,105 @@ impl HirEqInterExpr<'_, '_, '_> { } /// Checks whether two blocks are the same. + #[expect(clippy::similar_names)] fn eq_block(&mut self, left: &Block<'_>, right: &Block<'_>) -> bool { - match (left.stmts, left.expr, right.stmts, right.expr) { - ([], None, [], None) => { - // For empty blocks, check to see if the tokens are equal. This will catch the case where a macro - // expanded to nothing, or the cfg attribute was used. - let (Some(left), Some(right)) = ( - snippet_opt(self.inner.cx, left.span), - snippet_opt(self.inner.cx, right.span), - ) else { return true }; - let mut left_pos = 0; - let left = tokenize(&left) - .map(|t| { - let end = left_pos + t.len as usize; - let s = &left[left_pos..end]; - left_pos = end; - (t, s) - }) - .filter(|(t, _)| { - !matches!( - t.kind, - TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace - ) - }) - .map(|(_, s)| s); - let mut right_pos = 0; - let right = tokenize(&right) - .map(|t| { - let end = right_pos + t.len as usize; - let s = &right[right_pos..end]; - right_pos = end; - (t, s) - }) - .filter(|(t, _)| { - !matches!( - t.kind, - TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace - ) - }) - .map(|(_, s)| s); - left.eq(right) - }, - _ => { - over(left.stmts, right.stmts, |l, r| self.eq_stmt(l, r)) - && both(&left.expr, &right.expr, |l, r| self.eq_expr(l, r)) - }, + use TokenKind::{BlockComment, LineComment, Semi, Whitespace}; + if left.stmts.len() != right.stmts.len() { + return false; + } + let lspan = left.span.data(); + let rspan = right.span.data(); + if lspan.ctxt != SyntaxContext::root() && rspan.ctxt != SyntaxContext::root() { + // Don't try to check in between statements inside macros. + return over(left.stmts, right.stmts, |left, right| self.eq_stmt(left, right)) + && both(&left.expr, &right.expr, |left, right| self.eq_expr(left, right)); + } + if lspan.ctxt != rspan.ctxt { + return false; } + + let mut lstart = lspan.lo; + let mut rstart = rspan.lo; + + for (left, right) in left.stmts.iter().zip(right.stmts) { + if !self.eq_stmt(left, right) { + return false; + } +<<<<<<< HEAD +<<<<<<< HEAD + + // Try to detect any `cfg`ed statements or empty macro expansions. +======= +>>>>>>> 0b3c2ed81 (Search for inactive `cfg` attributes and empty macro expansion through) +======= + + // Try to detect any `cfg`ed statements or empty macro expansions. +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) + let Some(lstmt_span) = walk_span_to_context(left.span, lspan.ctxt) else { + return false; + }; + let Some(rstmt_span) = walk_span_to_context(right.span, rspan.ctxt) else { + return false; + }; + let lstmt_span = lstmt_span.data(); + let rstmt_span = rstmt_span.data(); + + if lstmt_span.lo < lstart && rstmt_span.lo < rstart { + // Can happen when macros expand to multiple statements, or rearrange statements. + // Nothing in between the statements to check in this case. + continue; +<<<<<<< HEAD +<<<<<<< HEAD + } + if lstmt_span.lo < lstart || rstmt_span.lo < rstart { +======= + } else if lstmt_span.lo < lstart || rstmt_span.lo < rstart { +>>>>>>> 0b3c2ed81 (Search for inactive `cfg` attributes and empty macro expansion through) +======= + } + if lstmt_span.lo < lstart || rstmt_span.lo < rstart { +>>>>>>> 58132cb3b (Improve `SpanlessEq`) + // Only one of the blocks had a weird macro. + return false; + } + if !eq_span_tokens(self.inner.cx, lstart..lstmt_span.lo, rstart..rstmt_span.lo, |t| { + !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi) + }) { + return false; + } + + lstart = lstmt_span.hi; + rstart = rstmt_span.hi; + } + + let (lend, rend) = match (left.expr, right.expr) { + (Some(left), Some(right)) => { + if !self.eq_expr(left, right) { + return false; + } + let Some(lexpr_span) = walk_span_to_context(left.span, lspan.ctxt) else { + return false; + }; + let Some(rexpr_span) = walk_span_to_context(right.span, rspan.ctxt) else { + return false; + }; + (lexpr_span.lo(), rexpr_span.lo()) + }, + (None, None) => (lspan.hi, rspan.hi), + (Some(_), None) | (None, Some(_)) => return false, + }; + + if lend < lstart && rend < rstart { + // Can happen when macros rearrange the input. + // Nothing in between the statements to check in this case. + return true; + } else if lend < lstart || rend < rstart { + // Only one of the blocks had a weird macro + return false; + } + eq_span_tokens(self.inner.cx, lstart..lend, rstart..rend, |t| { + !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi) + }) } fn should_ignore(&mut self, expr: &Expr<'_>) -> bool { @@ -207,7 +273,7 @@ impl HirEqInterExpr<'_, '_, '_> { #[expect(clippy::similar_names)] pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool { - if !self.inner.allow_side_effects && left.span.ctxt() != right.span.ctxt() { + if !self.check_ctxt(left.span.ctxt(), right.span.ctxt()) { return false; } @@ -301,6 +367,17 @@ impl HirEqInterExpr<'_, '_, '_> { (&ExprKind::Unary(l_op, le), &ExprKind::Unary(r_op, re)) => l_op == r_op && self.eq_expr(le, re), (&ExprKind::Array(l), &ExprKind::Array(r)) => self.eq_exprs(l, r), (&ExprKind::DropTemps(le), &ExprKind::DropTemps(re)) => self.eq_expr(le, re), +<<<<<<< HEAD + (&ExprKind::OffsetOf(l_container, ref l_fields), &ExprKind::OffsetOf(r_container, ref r_fields)) => { +======= +<<<<<<< HEAD + (&ExprKind::OffsetOf(l_container, l_fields), &ExprKind::OffsetOf(r_container, r_fields)) => { +======= + (&ExprKind::OffsetOf(l_container, ref l_fields), &ExprKind::OffsetOf(r_container, ref r_fields)) => { +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + self.eq_ty(l_container, r_container) && over(l_fields, r_fields, |l, r| l.name == r.name) + }, _ => false, }; (is_eq && (!self.should_ignore(left) || !self.should_ignore(right))) @@ -437,6 +514,45 @@ impl HirEqInterExpr<'_, '_, '_> { fn eq_type_binding(&mut self, left: &TypeBinding<'_>, right: &TypeBinding<'_>) -> bool { left.ident.name == right.ident.name && self.eq_ty(left.ty(), right.ty()) } + + fn check_ctxt(&mut self, left: SyntaxContext, right: SyntaxContext) -> bool { + if self.left_ctxt == left && self.right_ctxt == right { + return true; + } else if self.left_ctxt == left || self.right_ctxt == right { + // Only one context has changed. This can only happen if the two nodes are written differently. + return false; + } else if left != SyntaxContext::root() { + let mut left_data = left.outer_expn_data(); + let mut right_data = right.outer_expn_data(); + loop { + use TokenKind::{BlockComment, LineComment, Whitespace}; + if left_data.macro_def_id != right_data.macro_def_id + || (matches!(left_data.kind, ExpnKind::Macro(MacroKind::Bang, name) if name == sym::cfg) + && !eq_span_tokens(self.inner.cx, left_data.call_site, right_data.call_site, |t| { + !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. }) + })) + { + // Either a different chain of macro calls, or different arguments to the `cfg` macro. + return false; + } + let left_ctxt = left_data.call_site.ctxt(); + let right_ctxt = right_data.call_site.ctxt(); + if left_ctxt == SyntaxContext::root() && right_ctxt == SyntaxContext::root() { + break; + } + if left_ctxt == SyntaxContext::root() || right_ctxt == SyntaxContext::root() { + // Different lengths for the expansion stack. This can only happen if nodes are written differently, + // or shouldn't be compared to start with. + return false; + } + left_data = left_ctxt.outer_expn_data(); + right_data = right_ctxt.outer_expn_data(); + } + } + self.left_ctxt = left; + self.right_ctxt = right; + true + } } /// Some simple reductions like `{ return }` => `return` @@ -701,6 +817,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } } }, + ExprKind::OffsetOf(container, fields) => { + self.hash_ty(container); + for field in fields { + self.hash_name(field.name); + } + }, ExprKind::Let(Let { pat, init, ty, .. }) => { self.hash_expr(init); if let Some(ty) = ty { @@ -755,6 +877,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_expr(e); } }, + ExprKind::Become(f) => { + self.hash_expr(f); + }, ExprKind::Path(ref qpath) => { self.hash_qpath(qpath); }, @@ -1029,3 +1154,41 @@ pub fn hash_expr(cx: &LateContext<'_>, e: &Expr<'_>) -> u64 { h.hash_expr(e); h.finish() } + +<<<<<<< HEAD +<<<<<<< HEAD +#[expect(clippy::similar_names)] +======= +>>>>>>> 0b3c2ed81 (Search for inactive `cfg` attributes and empty macro expansion through) +======= +#[expect(clippy::similar_names)] +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +fn eq_span_tokens( + cx: &LateContext<'_>, + left: impl SpanRange, + right: impl SpanRange, + pred: impl Fn(TokenKind) -> bool, +) -> bool { + fn f(cx: &LateContext<'_>, left: Range, right: Range, pred: impl Fn(TokenKind) -> bool) -> bool { + if let Some(lsrc) = get_source_text(cx, left) + && let Some(lsrc) = lsrc.as_str() + && let Some(rsrc) = get_source_text(cx, right) + && let Some(rsrc) = rsrc.as_str() + { + let pred = |t: &(_, _)| pred(t.0); + let map = |(_, x)| x; + + let ltok = tokenize_with_text(lsrc) + .filter(pred) + .map(map); + let rtok = tokenize_with_text(rsrc) + .filter(pred) + .map(map); + ltok.eq(rtok) + } else { + // Unable to access the source. Conservatively assume the blocks aren't equal. + false + } + } + f(cx, left.into_range(), right.into_range(), pred) +} diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index f1d2ae220f81..eec589689f6a 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1,5 +1,6 @@ #![feature(array_chunks)] #![feature(box_patterns)] +#![feature(if_let_guard)] #![feature(let_chains)] #![feature(lint_reasons)] #![feature(never_type)] @@ -19,6 +20,12 @@ extern crate rustc_ast; extern crate rustc_ast_pretty; extern crate rustc_attr; +<<<<<<< HEAD +extern crate rustc_const_eval; +extern crate rustc_data_structures; +======= +>>>>>>> 5692677b3 (cleanup spaghetti code) +extern crate rustc_const_eval; extern crate rustc_data_structures; // The `rustc_driver` crate seems to be required in order to use the `rust_ast` crate. #[allow(unused_extern_crates)] @@ -72,10 +79,10 @@ pub use self::hir_utils::{ use core::ops::ControlFlow; use std::collections::hash_map::Entry; use std::hash::BuildHasherDefault; -use std::sync::OnceLock; -use std::sync::{Mutex, MutexGuard}; +use std::sync::{Mutex, MutexGuard, OnceLock}; use if_chain::if_chain; +use itertools::Itertools; use rustc_ast::ast::{self, LitKind, RangeLimits}; use rustc_ast::Attribute; use rustc_data_structures::fx::FxHashMap; @@ -84,12 +91,12 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::hir_id::{HirIdMap, HirIdSet}; use rustc_hir::intravisit::{walk_expr, FnKind, Visitor}; -use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk}; +use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk}; use rustc_hir::{ - self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness, Destination, - Expr, ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, IsAsync, Item, ItemKind, LangItem, Local, + self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Destination, Expr, + ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, IsAsync, Item, ItemKind, LangItem, Local, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, - TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp, + TraitItem, TraitItemRef, TraitRef, TyKind, UnOp, }; use rustc_lexer::{tokenize, TokenKind}; use rustc_lint::{LateContext, Level, Lint, LintContext}; @@ -102,15 +109,14 @@ use rustc_middle::ty::fast_reject::SimplifiedType::{ ArraySimplifiedType, BoolSimplifiedType, CharSimplifiedType, FloatSimplifiedType, IntSimplifiedType, PtrSimplifiedType, SliceSimplifiedType, StrSimplifiedType, UintSimplifiedType, }; +use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ - layout::IntegerExt, BorrowKind, ClosureKind, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, UpvarCapture, + BorrowKind, ClosureKind, FloatTy, IntTy, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, UintTy, UpvarCapture, }; -use rustc_middle::ty::{FloatTy, IntTy, UintTy}; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::SourceMap; -use rustc_span::sym; use rustc_span::symbol::{kw, Ident, Symbol}; -use rustc_span::Span; +use rustc_span::{sym, Span}; use rustc_target::abi::Integer; use crate::consts::{constant, miri_to_const, Constant}; @@ -197,31 +203,7 @@ pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option< /// } /// ``` pub fn in_constant(cx: &LateContext<'_>, id: HirId) -> bool { - let parent_id = cx.tcx.hir().get_parent_item(id).def_id; - match cx.tcx.hir().get_by_def_id(parent_id) { - Node::Item(&Item { - kind: ItemKind::Const(..) | ItemKind::Static(..) | ItemKind::Enum(..), - .. - }) - | Node::TraitItem(&TraitItem { - kind: TraitItemKind::Const(..), - .. - }) - | Node::ImplItem(&ImplItem { - kind: ImplItemKind::Const(..), - .. - }) - | Node::AnonConst(_) => true, - Node::Item(&Item { - kind: ItemKind::Fn(ref sig, ..), - .. - }) - | Node::ImplItem(&ImplItem { - kind: ImplItemKind::Fn(ref sig, _), - .. - }) => sig.header.constness == Constness::Const, - _ => false, - } + cx.tcx.hir().is_inside_const_context(id) } /// Checks if a `Res` refers to a constructor of a `LangItem` @@ -306,6 +288,19 @@ pub fn is_wild(pat: &Pat<'_>) -> bool { matches!(pat.kind, PatKind::Wild) } +/// Checks if the given `QPath` belongs to a type alias. +pub fn is_ty_alias(qpath: &QPath<'_>) -> bool { + match *qpath { +<<<<<<< HEAD + QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias | DefKind::AssocTy, ..)), +======= + QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias, ..)), +>>>>>>> e4f5d83fa (Fixed formatting.) + QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => { is_ty_alias(&qpath) }, + _ => false, + } +} + /// Checks if the method call given in `expr` belongs to the given trait. /// This is a deprecated function, consider using [`is_trait_method`]. pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) -> bool { @@ -339,6 +334,18 @@ pub fn is_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol) .map_or(false, |did| is_diag_trait_item(cx, did, diag_item)) } +/// Checks if the `def_id` belongs to a function that is part of a trait impl. +pub fn is_def_id_trait_method(cx: &LateContext<'_>, def_id: LocalDefId) -> bool { + if let Some(hir_id) = cx.tcx.opt_local_def_id_to_hir_id(def_id) + && let Node::Item(item) = cx.tcx.hir().get_parent(hir_id) + && let ItemKind::Impl(imp) = item.kind + { + imp.of_trait.is_some() + } else { + false + } +} + /// Checks if the given expression is a path referring an item on the trait /// that is marked with the given diagnostic item. /// @@ -823,7 +830,7 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath< false } -/// Return true if the expr is equal to `Default::default` when evaluated. +/// Returns true if the expr is equal to `Default::default` when evaluated. pub fn is_default_equivalent_call(cx: &LateContext<'_>, repl_func: &Expr<'_>) -> bool { if_chain! { if let hir::ExprKind::Path(ref repl_func_qpath) = repl_func.kind; @@ -1511,8 +1518,16 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti && let Some(min_val) = bnd_ty.numeric_min_val(cx.tcx) && let const_val = cx.tcx.valtree_to_const_val((bnd_ty, min_val.to_valtree())) && let min_const_kind = ConstantKind::from_value(const_val, bnd_ty) +<<<<<<< HEAD +<<<<<<< HEAD + && let Some(min_const) = miri_to_const(cx, min_const_kind) +======= && let Some(min_const) = miri_to_const(cx.tcx, min_const_kind) - && let Some((start_const, _)) = constant(cx, cx.typeck_results(), start) +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + && let Some(min_const) = miri_to_const(cx, min_const_kind) +>>>>>>> 0e1caa765 (Fix #10792) + && let Some(start_const) = constant(cx, cx.typeck_results(), start) { start_const == min_const } else { @@ -1527,8 +1542,16 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti && let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx) && let const_val = cx.tcx.valtree_to_const_val((bnd_ty, max_val.to_valtree())) && let max_const_kind = ConstantKind::from_value(const_val, bnd_ty) +<<<<<<< HEAD +<<<<<<< HEAD + && let Some(max_const) = miri_to_const(cx, max_const_kind) +======= && let Some(max_const) = miri_to_const(cx.tcx, max_const_kind) - && let Some((end_const, _)) = constant(cx, cx.typeck_results(), end) +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + && let Some(max_const) = miri_to_const(cx, max_const_kind) +>>>>>>> 0e1caa765 (Fix #10792) + && let Some(end_const) = constant(cx, cx.typeck_results(), end) { end_const == max_const } else { @@ -1560,7 +1583,7 @@ pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool return true; } let enclosing_body = cx.tcx.hir().enclosing_body_owner(e.hir_id); - if let Some((Constant::Int(v), _)) = constant(cx, cx.tcx.typeck(enclosing_body), e) { + if let Some(Constant::Int(v)) = constant(cx, cx.tcx.typeck(enclosing_body), e) { return value == v; } false @@ -2165,10 +2188,42 @@ pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_>, did: DefId) -> bool { .predicates .iter() .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); +<<<<<<< HEAD +======= +<<<<<<< HEAD + traits::impossible_predicates(cx.tcx, traits::elaborate(cx.tcx, predicates).collect::>()) +======= +>>>>>>> 4da6e7e06 (rebase attempt) traits::impossible_predicates( cx.tcx, +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD traits::elaborate_predicates(cx.tcx, predicates).collect::>(), +======= +======= +>>>>>>> 0963a66ab (Make elaborator generic) +======= + traits::elaborate_predicates(cx.tcx, predicates).collect::>(), +======= +>>>>>>> 4da6e7e06 (rebase attempt) + traits::elaborate(cx.tcx, predicates) + .collect::>(), +>>>>>>> 0963a66ab (Make elaborator generic) +======= + traits::elaborate(cx.tcx, predicates).collect::>(), +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +<<<<<<< HEAD +======= + traits::elaborate(cx.tcx, predicates).collect::>(), +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) + ) +======= ) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) } /// Returns the `DefId` of the callee if the given expression is a function or method call. @@ -2233,8 +2288,12 @@ pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option(exprs: &[T], hash: Hash, eq: Eq) -> Vec<(&T, &T)> where Hash: Fn(&T) -> u64, @@ -2408,7 +2467,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalDefId, f: impl Fn(&[Symbol /// Checks if the function containing the given `HirId` is a `#[test]` function /// -/// Note: Add `// compile-flags: --test` to UI tests with a `#[test]` function +/// Note: Add `//@compile-flags: --test` to UI tests with a `#[test]` function pub fn is_in_test_function(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { with_test_item_names(tcx, tcx.parent_module(id), |names| { tcx.hir() @@ -2430,7 +2489,7 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { /// Checks if the item containing the given `HirId` has `#[cfg(test)]` attribute applied /// -/// Note: Add `// compile-flags: --test` to UI tests with a `#[cfg(test)]` function +/// Note: Add `//@compile-flags: --test` to UI tests with a `#[cfg(test)]` function pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { fn is_cfg_test(attr: &Attribute) -> bool { if attr.has_name(sym::cfg) @@ -2452,7 +2511,7 @@ pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { /// Checks whether item either has `test` attribute applied, or /// is a module with `test` in its name. /// -/// Note: Add `// compile-flags: --test` to UI tests with a `#[test]` function +/// Note: Add `//@compile-flags: --test` to UI tests with a `#[test]` function pub fn is_test_module_or_function(tcx: TyCtxt<'_>, item: &Item<'_>) -> bool { is_in_test_function(tcx, item.hir_id()) || matches!(item.kind, ItemKind::Mod(..)) @@ -2503,6 +2562,17 @@ pub fn walk_to_expr_usage<'tcx, T>( None } +/// Tokenizes the input while keeping the text associated with each token. +pub fn tokenize_with_text(s: &str) -> impl Iterator { + let mut pos = 0; + tokenize(s).map(move |t| { + let end = pos + t.len; + let range = pos as usize..end as usize; + pos = end; + (t.kind, s.get(range).unwrap_or_default()) + }) +} + /// Checks whether a given span has any comment token /// This checks for all types of comment: line "//", block "/**", doc "///" "//!" pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool { @@ -2515,33 +2585,66 @@ pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool { }); } -/// Return all the comments a given span contains +/// Returns all the comments a given span contains +/// /// Comments are returned wrapped with their relevant delimiters pub fn span_extract_comment(sm: &SourceMap, span: Span) -> String { let snippet = sm.span_to_snippet(span).unwrap_or_default(); - let mut comments_buf: Vec = Vec::new(); - let mut index: usize = 0; - - for token in tokenize(&snippet) { - let token_range = index..(index + token.len as usize); - index += token.len as usize; - match token.kind { - TokenKind::BlockComment { .. } | TokenKind::LineComment { .. } => { - if let Some(comment) = snippet.get(token_range) { - comments_buf.push(comment.to_string()); - } - }, - _ => (), - } - } - - comments_buf.join("\n") + let res = tokenize_with_text(&snippet) + .filter(|(t, _)| matches!(t, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. })) + .map(|(_, s)| s) + .join("\n"); + res } pub fn span_find_starting_semi(sm: &SourceMap, span: Span) -> Span { sm.span_take_while(span, |&ch| ch == ' ' || ch == ';') } +/// Returns whether the given let pattern and else body can be turned into a question mark +/// +/// For this example: +/// ```ignore +/// let FooBar { a, b } = if let Some(a) = ex { a } else { return None }; +/// ``` +/// We get as parameters: +/// ```ignore +/// pat: Some(a) +/// else_body: return None +/// ``` + +/// And for this example: +/// ```ignore +/// let Some(FooBar { a, b }) = ex else { return None }; +/// ``` +/// We get as parameters: +/// ```ignore +/// pat: Some(FooBar { a, b }) +/// else_body: return None +/// ``` + +/// We output `Some(a)` in the first instance, and `Some(FooBar { a, b })` in the second, because +/// the question mark operator is applicable here. Callers have to check whether we are in a +/// constant or not. +pub fn pat_and_expr_can_be_question_mark<'a, 'hir>( + cx: &LateContext<'_>, + pat: &'a Pat<'hir>, + else_body: &Expr<'_>, +) -> Option<&'a Pat<'hir>> { + if let PatKind::TupleStruct(pat_path, [inner_pat], _) = pat.kind && + is_res_lang_ctor(cx, cx.qpath_res(&pat_path, pat.hir_id), OptionSome) && + !is_refutable(cx, inner_pat) && + let else_body = peel_blocks(else_body) && + let ExprKind::Ret(Some(ret_val)) = else_body.kind && + let ExprKind::Path(ret_path) = ret_val.kind && + is_res_lang_ctor(cx, cx.qpath_res(&ret_path, ret_val.hir_id), OptionNone) + { + Some(inner_pat) + } else { + None + } +} + macro_rules! op_utils { ($($name:ident $assign:ident)*) => { /// Binary operation traits like `LangItem::Add` diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index 62d388a5ece8..00f3abaec8a4 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -9,7 +9,7 @@ use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath}; use rustc_lint::LateContext; use rustc_span::def_id::DefId; use rustc_span::hygiene::{self, MacroKind, SyntaxContext}; -use rustc_span::{sym, BytePos, ExpnData, ExpnId, ExpnKind, Span, Symbol}; +use rustc_span::{sym, BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol}; use std::cell::RefCell; use std::ops::ControlFlow; use std::sync::atomic::{AtomicBool, Ordering}; @@ -362,7 +362,7 @@ thread_local! { /// able to access the many features of a [`LateContext`]. /// /// A thread local is used because [`FormatArgs`] is `!Send` and `!Sync`, we are making an - /// assumption that the early pass the populates the map and the later late passes will all be + /// assumption that the early pass that populates the map and the later late passes will all be /// running on the same thread. static AST_FORMAT_ARGS: RefCell> = { static CALLED: AtomicBool = AtomicBool::new(false); @@ -415,8 +415,18 @@ pub fn find_format_arg_expr<'hir, 'ast>( start: &'hir Expr<'hir>, target: &'ast FormatArgument, ) -> Result<&'hir rustc_hir::Expr<'hir>, &'ast rustc_ast::Expr> { + let SpanData { + lo, + hi, + ctxt, + parent: _, + } = target.expr.span.data(); + for_each_expr(start, |expr| { - if expr.span == target.expr.span { + // When incremental compilation is enabled spans gain a parent during AST to HIR lowering, + // since we're comparing an AST span to a HIR one we need to ignore the parent field + let data = expr.span.data(); + if data.lo == lo && data.hi == hi && data.ctxt == ctxt { ControlFlow::Break(expr) } else { ControlFlow::Continue(()) diff --git a/clippy_utils/src/mir/mod.rs b/clippy_utils/src/mir/mod.rs index 26c0015e87e0..131f3c0aa394 100644 --- a/clippy_utils/src/mir/mod.rs +++ b/clippy_utils/src/mir/mod.rs @@ -101,21 +101,26 @@ pub fn used_exactly_once(mir: &rustc_middle::mir::Body<'_>, local: rustc_middle: /// Returns the `mir::Body` containing the node associated with `hir_id`. #[allow(clippy::module_name_repetitions)] -pub fn enclosing_mir(tcx: TyCtxt<'_>, hir_id: HirId) -> &Body<'_> { +pub fn enclosing_mir(tcx: TyCtxt<'_>, hir_id: HirId) -> Option<&Body<'_>> { let body_owner_local_def_id = tcx.hir().enclosing_body_owner(hir_id); - tcx.optimized_mir(body_owner_local_def_id.to_def_id()) + if tcx.hir().body_owner_kind(body_owner_local_def_id).is_fn_or_closure() { + Some(tcx.optimized_mir(body_owner_local_def_id.to_def_id())) + } else { + None + } } /// Tries to determine the `Local` corresponding to `expr`, if any. /// This function is expensive and should be used sparingly. pub fn expr_local(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> Option { - let mir = enclosing_mir(tcx, expr.hir_id); - mir.local_decls.iter_enumerated().find_map(|(local, local_decl)| { - if local_decl.source_info.span == expr.span { - Some(local) - } else { - None - } + enclosing_mir(tcx, expr.hir_id).and_then(|mir| { + mir.local_decls.iter_enumerated().find_map(|(local, local_decl)| { + if local_decl.source_info.span == expr.span { + Some(local) + } else { + None + } + }) }) } diff --git a/clippy_utils/src/mir/possible_borrower.rs b/clippy_utils/src/mir/possible_borrower.rs index 920ce8e655be..703985b9d4b3 100644 --- a/clippy_utils/src/mir/possible_borrower.rs +++ b/clippy_utils/src/mir/possible_borrower.rs @@ -1,11 +1,15 @@ -use super::{possible_origin::PossibleOriginVisitor, transitive_relation::TransitiveRelation}; +use super::possible_origin::PossibleOriginVisitor; +use super::transitive_relation::TransitiveRelation; use crate::ty::is_copy; use rustc_data_structures::fx::FxHashMap; use rustc_index::bit_set::{BitSet, HybridBitSet}; use rustc_lint::LateContext; -use rustc_middle::mir::{self, visit::Visitor as _, Mutability}; -use rustc_middle::ty::{self, visit::TypeVisitor, TyCtxt}; -use rustc_mir_dataflow::{impls::MaybeStorageLive, Analysis, ResultsCursor}; +use rustc_middle::mir::visit::Visitor as _; +use rustc_middle::mir::{self, Mutability}; +use rustc_middle::ty::visit::TypeVisitor; +use rustc_middle::ty::{self, TyCtxt}; +use rustc_mir_dataflow::impls::MaybeStorageLive; +use rustc_mir_dataflow::{Analysis, ResultsCursor}; use std::borrow::Cow; use std::ops::ControlFlow; diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index e05de2dc99c0..acca6e89b16f 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -19,8 +19,21 @@ macro_rules! msrv_aliases { // names may refer to stabilized feature flags or library items msrv_aliases! { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> b1acbde61 (Add msrv check and make test pass) + 1,71,0 { TUPLE_ARRAY_CONVERSIONS } + 1,70,0 { OPTION_IS_SOME_AND } +======= + 1,70,0 { OPT_IS_SOME_AND } +>>>>>>> c60222dc1 (changed the msrv to 1.70 to suggest `is_some_and`) +======= + 1,70,0 { OPTION_IS_SOME_AND } +>>>>>>> a693cbc1b (changed msrv name for consistency & changed nested if for style) 1,68,0 { PATH_MAIN_SEPARATOR_STR } - 1,65,0 { LET_ELSE } + 1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS } 1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE } 1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY } 1,55,0 { SEEK_REWIND } @@ -28,7 +41,7 @@ msrv_aliases! { 1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST } 1,51,0 { BORROW_AS_PTR, SEEK_FROM_CURRENT, UNSIGNED_ABS } 1,50,0 { BOOL_THEN, CLAMP } - 1,47,0 { TAU, IS_ASCII_DIGIT_CONST } + 1,47,0 { TAU, IS_ASCII_DIGIT_CONST, ARRAY_IMPL_ANY_LEN } 1,46,0 { CONST_IF_MATCH } 1,45,0 { STR_STRIP_PREFIX } 1,43,0 { LOG2_10, LOG10_2 } @@ -42,11 +55,21 @@ msrv_aliases! { 1,34,0 { TRY_FROM } 1,30,0 { ITERATOR_FIND_MAP, TOOL_ATTRIBUTES } 1,28,0 { FROM_BOOL } + 1,27,0 { ITERATOR_TRY_FOLD } 1,26,0 { RANGE_INCLUSIVE, STRING_RETAIN } 1,24,0 { IS_ASCII_DIGIT } 1,18,0 { HASH_MAP_RETAIN, HASH_SET_RETAIN } 1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR } 1,16,0 { STR_REPEAT } +<<<<<<< HEAD +<<<<<<< HEAD + 1,15,0 { MAYBE_BOUND_IN_WHERE } +======= + 1,15,0 { COMBINED_MAYBE_BOUND } +>>>>>>> 87c28b946 ([`type_repetition_in_bounds`]: respect msrv for combining maybe bounds) +======= + 1,15,0 { MAYBE_BOUND_IN_WHERE } +>>>>>>> 33b6d0d20 (rename MSRV alias, add MSRV to lint doc) } fn parse_msrv(msrv: &str, sess: Option<&Session>, span: Option) -> Option { diff --git a/clippy_utils/src/numeric_literal.rs b/clippy_utils/src/numeric_literal.rs index c225398ad2a8..bbe4149fe2ab 100644 --- a/clippy_utils/src/numeric_literal.rs +++ b/clippy_utils/src/numeric_literal.rs @@ -161,7 +161,7 @@ impl<'a> NumericLiteral<'a> { } if let Some((separator, exponent)) = self.exponent { - if exponent != "0" { + if !exponent.is_empty() && exponent != "0" { output.push_str(separator); Self::group_digits(&mut output, exponent, group_size, true, false); } diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 9be2d0eae80a..50541ed1c1a9 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -15,7 +15,6 @@ pub const APPLICABILITY_VALUES: [[&str; 3]; 4] = [ ]; #[cfg(feature = "internal")] pub const DIAGNOSTIC_BUILDER: [&str; 3] = ["rustc_errors", "diagnostic_builder", "DiagnosticBuilder"]; -pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"]; pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"]; pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"]; pub const BTREESET_ITER: [&str; 6] = ["alloc", "collections", "btree", "set", "BTreeSet", "iter"]; @@ -93,15 +92,14 @@ pub const PTR_WRITE_UNALIGNED: [&str; 3] = ["core", "ptr", "write_unaligned"]; pub const PTR_WRITE_VOLATILE: [&str; 3] = ["core", "ptr", "write_volatile"]; pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"]; pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"]; -pub const RC_PTR_EQ: [&str; 4] = ["alloc", "rc", "Rc", "ptr_eq"]; pub const REFCELL_REF: [&str; 3] = ["core", "cell", "Ref"]; pub const REFCELL_REFMUT: [&str; 3] = ["core", "cell", "RefMut"]; -pub const REGEX_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "unicode", "RegexBuilder", "new"]; -pub const REGEX_BYTES_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "bytes", "RegexBuilder", "new"]; -pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"]; -pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"]; -pub const REGEX_NEW: [&str; 4] = ["regex", "re_unicode", "Regex", "new"]; -pub const REGEX_SET_NEW: [&str; 5] = ["regex", "re_set", "unicode", "RegexSet", "new"]; +pub const REGEX_BUILDER_NEW: [&str; 3] = ["regex", "RegexBuilder", "new"]; +pub const REGEX_BYTES_BUILDER_NEW: [&str; 4] = ["regex", "bytes", "RegexBuilder", "new"]; +pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "bytes", "Regex", "new"]; +pub const REGEX_BYTES_SET_NEW: [&str; 4] = ["regex", "bytes", "RegexSet", "new"]; +pub const REGEX_NEW: [&str; 3] = ["regex", "Regex", "new"]; +pub const REGEX_SET_NEW: [&str; 3] = ["regex", "RegexSet", "new"]; pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"]; pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"]; pub const SLICE_FROM_RAW_PARTS: [&str; 4] = ["core", "slice", "raw", "from_raw_parts"]; @@ -125,8 +123,6 @@ pub const STRING_NEW: [&str; 4] = ["alloc", "string", "String", "new"]; pub const STR_BYTES: [&str; 4] = ["core", "str", "", "bytes"]; pub const STR_CHARS: [&str; 4] = ["core", "str", "", "chars"]; pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "", "ends_with"]; -pub const STR_FROM_UTF8: [&str; 4] = ["core", "str", "converts", "from_utf8"]; -pub const STR_FROM_UTF8_UNCHECKED: [&str; 4] = ["core", "str", "converts", "from_utf8_unchecked"]; pub const STR_LEN: [&str; 4] = ["core", "str", "", "len"]; pub const STR_STARTS_WITH: [&str; 4] = ["core", "str", "", "starts_with"]; #[cfg(feature = "internal")] @@ -159,3 +155,12 @@ pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"]; pub const PTR_NON_NULL: [&str; 4] = ["core", "ptr", "non_null", "NonNull"]; pub const INSTANT_NOW: [&str; 4] = ["std", "time", "Instant", "now"]; pub const INSTANT: [&str; 3] = ["std", "time", "Instant"]; +pub const VEC_IS_EMPTY: [&str; 4] = ["alloc", "vec", "Vec", "is_empty"]; +pub const VEC_POP: [&str; 4] = ["alloc", "vec", "Vec", "pop"]; +pub const OPTION_UNWRAP: [&str; 4] = ["core", "option", "Option", "unwrap"]; +pub const OPTION_EXPECT: [&str; 4] = ["core", "option", "Option", "expect"]; +<<<<<<< HEAD +pub const FORMATTER: [&str; 3] = ["core", "fmt", "Formatter"]; +pub const DEBUG_STRUCT: [&str; 4] = ["core", "fmt", "builders", "DebugStruct"]; +======= +>>>>>>> e4f5d83fa (Fixed formatting.) diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index d66640ba0b7a..6a5b2ead54e9 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -4,52 +4,61 @@ // differ from the time of `rustc` even if the name stays the same. use crate::msrvs::Msrv; +<<<<<<< HEAD +<<<<<<< HEAD +use hir::LangItem; +======= +use hir::{Constness, LangItem}; +>>>>>>> 0e233492d (use trait solver instead; created spaghetti code) +======= +use hir::LangItem; +>>>>>>> 5692677b3 (cleanup spaghetti code) +use rustc_const_eval::transform::check_consts::ConstCx; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_infer::infer::TyCtxtInferExt; +use rustc_infer::traits::Obligation; use rustc_middle::mir::{ Body, CastKind, NonDivergingIntrinsic, NullOp, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; +<<<<<<< HEAD +<<<<<<< HEAD +use rustc_middle::traits::{ImplSource, ObligationCause}; +use rustc_middle::ty::adjustment::PointerCast; +use rustc_middle::ty::subst::GenericArgKind; +<<<<<<< HEAD +use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; +======= +use rustc_middle::traits::ObligationCause; +======= +use rustc_middle::traits::{ImplSource, ObligationCause}; +>>>>>>> 5692677b3 (cleanup spaghetti code) use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt}; +>>>>>>> 0e233492d (use trait solver instead; created spaghetti code) +use rustc_middle::ty::{BoundConstness, TraitRef}; +======= +use rustc_middle::ty::{self, BoundConstness, TraitRef, Ty, TyCtxt}; +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) use rustc_semver::RustcVersion; use rustc_span::symbol::sym; use rustc_span::Span; +<<<<<<< HEAD +<<<<<<< HEAD +use rustc_trait_selection::traits::{ObligationCtxt, SelectionContext}; +======= +use rustc_trait_selection::traits::SelectionContext; +>>>>>>> 0e233492d (use trait solver instead; created spaghetti code) +======= +use rustc_trait_selection::traits::{ObligationCtxt, SelectionContext}; +>>>>>>> 5692677b3 (cleanup spaghetti code) use std::borrow::Cow; type McfResult = Result<(), (Span, Cow<'static, str>)>; pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) -> McfResult { let def_id = body.source.def_id(); - let mut current = def_id; - loop { - let predicates = tcx.predicates_of(current); - for (predicate, _) in predicates.predicates { - match predicate.kind().skip_binder() { - ty::PredicateKind::Clause( - ty::Clause::RegionOutlives(_) - | ty::Clause::TypeOutlives(_) - | ty::Clause::Projection(_) - | ty::Clause::Trait(..) - | ty::Clause::ConstArgHasType(..), - ) - | ty::PredicateKind::WellFormed(_) - | ty::PredicateKind::ConstEvaluatable(..) - | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::TypeWellFormedFromEnv(..) => continue, - ty::PredicateKind::AliasRelate(..) => panic!("alias relate predicate on function: {predicate:#?}"), - ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {predicate:#?}"), - ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {predicate:#?}"), - ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {predicate:#?}"), - ty::PredicateKind::Coerce(_) => panic!("coerce predicate on function: {predicate:#?}"), - ty::PredicateKind::Ambiguous => panic!("ambiguous predicate on function: {predicate:#?}"), - } - } - match predicates.parent { - Some(parent) => current = parent, - None => break, - } - } for local in &body.local_decls { check_ty(tcx, local.ty, local.source_info.span)?; @@ -61,7 +70,7 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) body.local_decls.iter().next().unwrap().source_info.span, )?; - for bb in body.basic_blocks.iter() { + for bb in &*body.basic_blocks { check_terminator(tcx, body, bb.terminator(), msrv)?; for stmt in &bb.statements { check_statement(tcx, body, def_id, stmt)?; @@ -89,7 +98,7 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult { return Err((span, "function pointers in const fn are unstable".into())); }, ty::Dynamic(preds, _, _) => { - for pred in preds.iter() { + for pred in *preds { match pred.skip_binder() { ty::ExistentialPredicate::AutoTrait(_) | ty::ExistentialPredicate::Projection(_) => { return Err(( @@ -141,18 +150,18 @@ fn check_rvalue<'tcx>( | CastKind::FloatToFloat | CastKind::FnPtrToPtr | CastKind::PtrToPtr - | CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer), + | CastKind::PointerCoercion(PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer), operand, _, ) => check_operand(tcx, operand, span, body), Rvalue::Cast( - CastKind::Pointer( - PointerCast::UnsafeFnPointer | PointerCast::ClosureFnPointer(_) | PointerCast::ReifyFnPointer, + CastKind::PointerCoercion( + PointerCoercion::UnsafeFnPointer | PointerCoercion::ClosureFnPointer(_) | PointerCoercion::ReifyFnPointer, ), _, _, ) => Err((span, "function pointer casts are not allowed in const fn".into())), - Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), op, cast_ty) => { + Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), op, cast_ty) => { let pointee_ty = if let Some(deref_ty) = cast_ty.builtin_deref(true) { deref_ty.ty } else { @@ -194,7 +203,17 @@ fn check_rvalue<'tcx>( )) } }, - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::ShallowInitBox(_, _) => Ok(()), +<<<<<<< HEAD + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) | Rvalue::ShallowInitBox(_, _) => Ok(()), +======= +<<<<<<< HEAD + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) | Rvalue::ShallowInitBox(_, _) => { + Ok(()) + }, +======= + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) | Rvalue::ShallowInitBox(_, _) => Ok(()), +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) Rvalue::UnaryOp(_, operand) => { let ty = operand.ty(body, tcx); if ty.is_integral() || ty.is_bool() { @@ -254,7 +273,30 @@ fn check_statement<'tcx>( fn check_operand<'tcx>(tcx: TyCtxt<'tcx>, operand: &Operand<'tcx>, span: Span, body: &Body<'tcx>) -> McfResult { match operand { - Operand::Move(place) | Operand::Copy(place) => check_place(tcx, *place, span, body), +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 9bc5a146f (remove `in_move`) + Operand::Move(place) => { + if !place.projection.as_ref().is_empty() + && !is_ty_const_destruct(tcx, place.ty(&body.local_decls, tcx).ty, body) + { + return Err(( + span, + "cannot drop locals with a non constant destructor in const fn".into(), + )); + } + + check_place(tcx, *place, span, body) + }, + Operand::Copy(place) => check_place(tcx, *place, span, body), +<<<<<<< HEAD +======= + Operand::Move(place) => check_place(tcx, *place, span, body, true), + Operand::Copy(place) => check_place(tcx, *place, span, body, false), +>>>>>>> 5692677b3 (cleanup spaghetti code) +======= +>>>>>>> 9bc5a146f (remove `in_move`) Operand::Constant(c) => match c.check_static_ptr(tcx) { Some(_) => Err((span, "cannot access `static` items in const fn".into())), None => Ok(()), @@ -262,13 +304,49 @@ fn check_operand<'tcx>(tcx: TyCtxt<'tcx>, operand: &Operand<'tcx>, span: Span, b } } +<<<<<<< HEAD +<<<<<<< HEAD +fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &Body<'tcx>) -> McfResult { +<<<<<<< HEAD +<<<<<<< HEAD + for (base, elem) in place.as_ref().iter_projections() { +======= +======= +fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &Body<'tcx>, in_move: bool) -> McfResult { +>>>>>>> 5692677b3 (cleanup spaghetti code) +======= fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &Body<'tcx>) -> McfResult { +>>>>>>> 9bc5a146f (remove `in_move`) let mut cursor = place.projection.as_ref(); + while let [ref proj_base @ .., elem] = *cursor { cursor = proj_base; +>>>>>>> 0e233492d (use trait solver instead; created spaghetti code) +======= + for (base, elem) in place.as_ref().iter_projections() { +>>>>>>> 66590ba41 (use PlaceRef abstractions) match elem { +<<<<<<< HEAD +<<<<<<< HEAD ProjectionElem::Field(..) => { + let base_ty = base.ty(body, tcx).ty; +<<<<<<< HEAD +======= + ProjectionElem::Field(_, ty) => { + if !is_ty_const_destruct(tcx, ty, body) && in_move { + return Err(( + span, + "cannot drop locals with a non constant destructor in const fn".into(), + )); + } + +======= + ProjectionElem::Field(..) => { +>>>>>>> a495fa06d (remove unnecessary checks) let base_ty = Place::ty_from(place.local, proj_base, body, tcx).ty; +>>>>>>> 5692677b3 (cleanup spaghetti code) +======= +>>>>>>> 66590ba41 (use PlaceRef abstractions) if let Some(def) = base_ty.ty_adt_def() { // No union field accesses in `const fn` if def.is_union() { @@ -301,24 +379,52 @@ fn check_terminator<'tcx>( | TerminatorKind::Goto { .. } | TerminatorKind::Return | TerminatorKind::Resume + | TerminatorKind::Terminate | TerminatorKind::Unreachable => Ok(()), +<<<<<<< HEAD +<<<<<<< HEAD + TerminatorKind::Drop { place, .. } => { + if !is_ty_const_destruct(tcx, place.ty(&body.local_decls, tcx).ty, body) { + return Err(( + span, + "cannot drop locals with a non constant destructor in const fn".into(), + )); + } + Ok(()) + }, +======= - TerminatorKind::Drop { place, .. } => check_place(tcx, *place, span, body), +======= +>>>>>>> 0e233492d (use trait solver instead; created spaghetti code) + TerminatorKind::Drop { place, .. } => { + if !is_ty_const_destruct(tcx, place.ty(&body.local_decls, tcx).ty, body) { + return Err(( + span, + "cannot drop locals with a non constant destructor in const fn".into(), + )); + } + Ok(()) + }, +<<<<<<< HEAD +>>>>>>> e24fc9af2 (Fix `missing_const_for_fn` not checking `~const Destruct`) +======= +>>>>>>> 0e233492d (use trait solver instead; created spaghetti code) TerminatorKind::SwitchInt { discr, targets: _ } => check_operand(tcx, discr, span, body), +<<<<<<< HEAD +======= - TerminatorKind::Abort => Err((span, "abort is not stable in const fn".into())), +>>>>>>> e4f5d83fa (Fixed formatting.) TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => { Err((span, "const fn generators are unstable".into())) }, - TerminatorKind::Call { func, args, - from_hir_call: _, + call_source: _, destination: _, target: _, - cleanup: _, + unwind: _, fn_span: _, } => { let fn_ty = func.ty(body, tcx); @@ -355,15 +461,13 @@ fn check_terminator<'tcx>( Err((span, "can only call other const fns within const fn".into())) } }, - TerminatorKind::Assert { cond, expected: _, msg: _, target: _, - cleanup: _, + unwind: _, } => check_operand(tcx, cond, span, body), - TerminatorKind::InlineAsm { .. } => Err((span, "cannot use inline assembly in const fn".into())), } } @@ -377,8 +481,7 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool { // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262. // HACK(nilstrieb): CURRENT_RUSTC_VERSION can return versions like 1.66.0-dev. `rustc-semver` - // doesn't accept the `-dev` version number so we have to strip it - // off. + // doesn't accept the `-dev` version number so we have to strip it off. let short_version = since .as_str() .split('-') @@ -396,3 +499,73 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool { } }) } + +<<<<<<< HEAD +<<<<<<< HEAD +#[expect(clippy::similar_names)] // bit too pedantic +======= +>>>>>>> 0e233492d (use trait solver instead; created spaghetti code) +======= +#[expect(clippy::similar_names)] // bit too pedantic +>>>>>>> 5692677b3 (cleanup spaghetti code) +fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool { + // Avoid selecting for simple cases, such as builtin types. + if ty::util::is_trivially_const_drop(ty) { + return true; + } + + let obligation = Obligation::new( + tcx, + ObligationCause::dummy_with_span(body.span), +<<<<<<< HEAD +<<<<<<< HEAD + ConstCx::new(tcx, body).param_env.with_const(), + TraitRef::from_lang_item(tcx, LangItem::Destruct, body.span, [ty]).with_constness(BoundConstness::ConstIfConst), + ); + + let infcx = tcx.infer_ctxt().build(); + let mut selcx = SelectionContext::new(&infcx); + let Some(impl_src) = selcx.select(&obligation).ok().flatten() else { + return false; + }; + + if !matches!( + impl_src, + ImplSource::Builtin(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst) + ) { + return false; + } + + let ocx = ObligationCtxt::new(&infcx); + ocx.register_obligations(impl_src.nested_obligations()); + ocx.select_all_or_error().is_empty() +======= + ConstCx::new(tcx, body).param_env.with_constness(Constness::Const), +======= + ConstCx::new(tcx, body).param_env.with_const(), +>>>>>>> 5692677b3 (cleanup spaghetti code) + TraitRef::from_lang_item(tcx, LangItem::Destruct, body.span, [ty]).with_constness(BoundConstness::ConstIfConst), + ); + + let infcx = tcx.infer_ctxt().build(); + let mut selcx = SelectionContext::new(&infcx); +<<<<<<< HEAD + selcx.select(&obligation).is_ok() && fields_all_const_destruct +>>>>>>> 0e233492d (use trait solver instead; created spaghetti code) +======= + let Some(impl_src) = selcx.select(&obligation).ok().flatten() else { + return false; + }; + + if !matches!( + impl_src, + ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst) + ) { + return false; + } + + let ocx = ObligationCtxt::new(&infcx); + ocx.register_obligations(impl_src.nested_obligations()); + ocx.select_all_or_error().is_empty() +>>>>>>> 5692677b3 (cleanup spaghetti code) +} diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index 62fa37660fad..68218b8a4aeb 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -2,14 +2,63 @@ #![allow(clippy::module_name_repetitions)] +use rustc_data_structures::sync::Lrc; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind}; +use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource}; use rustc_lint::{LateContext, LintContext}; use rustc_session::Session; -use rustc_span::hygiene; use rustc_span::source_map::{original_sp, SourceMap}; -use rustc_span::{BytePos, Pos, Span, SpanData, SyntaxContext, DUMMY_SP}; +use rustc_span::{hygiene, BytePos, Pos, SourceFile, Span, SpanData, SyntaxContext, DUMMY_SP}; use std::borrow::Cow; +use std::ops::Range; + +/// A type which can be converted to the range portion of a `Span`. +pub trait SpanRange { + fn into_range(self) -> Range; +} +impl SpanRange for Span { + fn into_range(self) -> Range { + let data = self.data(); + data.lo..data.hi + } +} +impl SpanRange for SpanData { + fn into_range(self) -> Range { + self.lo..self.hi + } +} +impl SpanRange for Range { + fn into_range(self) -> Range { + self + } +} + +pub struct SourceFileRange { + pub sf: Lrc, + pub range: Range, +} +impl SourceFileRange { + /// Attempts to get the text from the source file. This can fail if the source text isn't + /// loaded. + pub fn as_str(&self) -> Option<&str> { + self.sf.src.as_ref().and_then(|x| x.get(self.range.clone())) + } +} + +/// Gets the source file, and range in the file, of the given span. Returns `None` if the span +/// extends through multiple files, or is malformed. +pub fn get_source_text(cx: &impl LintContext, sp: impl SpanRange) -> Option { + fn f(sm: &SourceMap, sp: Range) -> Option { + let start = sm.lookup_byte_offset(sp.start); + let end = sm.lookup_byte_offset(sp.end); + if !Lrc::ptr_eq(&start.sf, &end.sf) || start.pos > end.pos { + return None; + } + let range = start.pos.to_usize()..end.pos.to_usize(); + Some(SourceFileRange { sf: start.sf, range }) + } + f(cx.sess().source_map(), sp.into_range()) +} /// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`. pub fn expr_block( @@ -21,11 +70,23 @@ pub fn expr_block( app: &mut Applicability, ) -> String { let (code, from_macro) = snippet_block_with_context(cx, expr.span, outer, default, indent_relative_to, app); - if from_macro { - format!("{{ {code} }}") - } else if let ExprKind::Block(_, _) = expr.kind { + if !from_macro && + let ExprKind::Block(block, _) = expr.kind && +<<<<<<< HEAD +<<<<<<< HEAD +======= + // TODO: Is this enough UnsafeSource::UserProvided, or should CompilerGenerated be also included? +>>>>>>> e92614818 (Fix unsafe blocks) +======= +>>>>>>> 68df61ebd (remove todo) + block.rules != BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) + { format!("{code}") } else { + // FIXME: add extra indent for the unsafe blocks: + // original code: unsafe { ... } + // result code: { unsafe { ... } } + // desired code: {\n unsafe { ... }\n} format!("{{ {code} }}") } } diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index a5a4a921d94e..45303cf558c5 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -139,6 +139,7 @@ impl<'a> Sugg<'a> { | hir::ExprKind::Field(..) | hir::ExprKind::Index(..) | hir::ExprKind::InlineAsm(..) + | hir::ExprKind::OffsetOf(..) | hir::ExprKind::ConstBlock(..) | hir::ExprKind::Lit(..) | hir::ExprKind::Loop(..) @@ -146,6 +147,7 @@ impl<'a> Sugg<'a> { | hir::ExprKind::Path(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::Ret(..) + | hir::ExprKind::Become(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Tup(..) | hir::ExprKind::Err(_) => Sugg::NonParen(get_snippet(expr.span)), @@ -161,8 +163,17 @@ impl<'a> Sugg<'a> { get_snippet(lhs.span), get_snippet(rhs.span), ), +<<<<<<< HEAD hir::ExprKind::Cast(lhs, ty) => Sugg::BinOp(AssocOp::As, get_snippet(lhs.span), get_snippet(ty.span)), - hir::ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::Colon, get_snippet(lhs.span), get_snippet(ty.span)), +======= +<<<<<<< HEAD + hir::ExprKind::Cast(lhs, ty) | +======= + hir::ExprKind::Cast(lhs, ty) => Sugg::BinOp(AssocOp::As, get_snippet(lhs.span), get_snippet(ty.span)), +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + //FIXME(chenyukang), remove this after type ascription is removed from AST + hir::ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::As, get_snippet(lhs.span), get_snippet(ty.span)), } } @@ -197,6 +208,7 @@ impl<'a> Sugg<'a> { | ast::ExprKind::ForLoop(..) | ast::ExprKind::Index(..) | ast::ExprKind::InlineAsm(..) + | ast::ExprKind::OffsetOf(..) | ast::ExprKind::ConstBlock(..) | ast::ExprKind::Lit(..) | ast::ExprKind::IncludedBytes(..) @@ -208,6 +220,7 @@ impl<'a> Sugg<'a> { | ast::ExprKind::Path(..) | ast::ExprKind::Repeat(..) | ast::ExprKind::Ret(..) + | ast::ExprKind::Become(..) | ast::ExprKind::Yeet(..) | ast::ExprKind::FormatArgs(..) | ast::ExprKind::Struct(..) @@ -251,13 +264,24 @@ impl<'a> Sugg<'a> { snippet_with_context(cx, lhs.span, ctxt, default, app).0, snippet_with_context(cx, rhs.span, ctxt, default, app).0, ), +<<<<<<< HEAD +======= +<<<<<<< HEAD + ast::ExprKind::Cast(ref lhs, ref ty) | +======= +>>>>>>> 4da6e7e06 (rebase attempt) ast::ExprKind::Cast(ref lhs, ref ty) => Sugg::BinOp( AssocOp::As, snippet_with_context(cx, lhs.span, ctxt, default, app).0, snippet_with_context(cx, ty.span, ctxt, default, app).0, ), +<<<<<<< HEAD +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + //FIXME(chenyukang), remove this after type ascription is removed from AST ast::ExprKind::Type(ref lhs, ref ty) => Sugg::BinOp( - AssocOp::Colon, + AssocOp::As, snippet_with_context(cx, lhs.span, ctxt, default, app).0, snippet_with_context(cx, ty.span, ctxt, default, app).0, ), @@ -390,11 +414,10 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String { AssocOp::As => format!("{lhs} as {rhs}"), AssocOp::DotDot => format!("{lhs}..{rhs}"), AssocOp::DotDotEq => format!("{lhs}..={rhs}"), - AssocOp::Colon => format!("{lhs}: {rhs}"), } } -/// Return `true` if `sugg` is enclosed in parenthesis. +/// Returns `true` if `sugg` is enclosed in parenthesis. pub fn has_enclosing_paren(sugg: impl AsRef) -> bool { let mut chars = sugg.as_ref().chars(); if chars.next() == Some('(') { @@ -600,13 +623,23 @@ enum Associativity { #[must_use] fn associativity(op: AssocOp) -> Associativity { use rustc_ast::util::parser::AssocOp::{ - Add, As, Assign, AssignOp, BitAnd, BitOr, BitXor, Colon, Divide, DotDot, DotDotEq, Equal, Greater, +<<<<<<< HEAD + Add, As, Assign, AssignOp, BitAnd, BitOr, BitXor, Divide, DotDot, DotDotEq, Equal, Greater, + GreaterEqual, LAnd, LOr, Less, LessEqual, Modulus, Multiply, NotEqual, ShiftLeft, ShiftRight, Subtract, +======= +<<<<<<< HEAD + Add, As, Assign, AssignOp, BitAnd, BitOr, BitXor, Divide, DotDot, DotDotEq, Equal, Greater, GreaterEqual, LAnd, + LOr, Less, LessEqual, Modulus, Multiply, NotEqual, ShiftLeft, ShiftRight, Subtract, +======= + Add, As, Assign, AssignOp, BitAnd, BitOr, BitXor, Divide, DotDot, DotDotEq, Equal, Greater, GreaterEqual, LAnd, LOr, Less, LessEqual, Modulus, Multiply, NotEqual, ShiftLeft, ShiftRight, Subtract, +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) }; match op { Assign | AssignOp(_) => Associativity::Right, - Add | BitAnd | BitOr | BitXor | LAnd | LOr | Multiply | As | Colon => Associativity::Both, + Add | BitAnd | BitOr | BitXor | LAnd | LOr | Multiply | As => Associativity::Both, Divide | Equal | Greater | GreaterEqual | Less | LessEqual | Modulus | NotEqual | ShiftLeft | ShiftRight | Subtract => Associativity::Left, DotDot | DotDotEq => Associativity::None, @@ -742,7 +775,7 @@ impl DiagnosticExt for rustc_errors::Diagnostic { if let Some(indent) = indentation(cx, item) { let span = item.with_hi(item.lo()); - self.span_suggestion(span, msg, format!("{attr}\n{indent}"), applicability); + self.span_suggestion(span, msg.to_string(), format!("{attr}\n{indent}"), applicability); } } @@ -763,7 +796,7 @@ impl DiagnosticExt for rustc_errors::Diagnostic { }) .collect::(); - self.span_suggestion(span, msg, format!("{new_item}\n{indent}"), applicability); + self.span_suggestion(span, msg.to_string(), format!("{new_item}\n{indent}"), applicability); } } @@ -780,7 +813,7 @@ impl DiagnosticExt for rustc_errors::Diagnostic { } } - self.span_suggestion(remove_span, msg, "", applicability); + self.span_suggestion(remove_span, msg.to_string(), "", applicability); } } @@ -943,7 +976,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> { }, // item is used in a call // i.e.: `Call`: `|x| please(x)` or `MethodCall`: `|x| [1, 2, 3].contains(x)` - ExprKind::Call(_, [call_args @ ..]) | ExprKind::MethodCall(_, _, [call_args @ ..], _) => { + ExprKind::Call(_, call_args) | ExprKind::MethodCall(_, _, call_args, _) => { let expr = self.cx.tcx.hir().expect_expr(cmt.hir_id); let arg_ty_kind = self.cx.typeck_results().expr_ty(expr).kind(); diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 9449f0b55674..d5b68d700da6 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -9,18 +9,16 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety}; -use rustc_infer::infer::{ - type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, - TyCtxtInferExt, -}; +use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::interpret::{ConstValue, Scalar}; +use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ - self, layout::ValidityRequirement, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv, - Predicate, PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, TypeVisitor, UintTy, VariantDef, VariantDiscr, + self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, IntTy, List, ParamEnv, + Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, + UintTy, VariantDef, VariantDiscr, }; -use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_span::symbol::Ident; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; use rustc_target::abi::{Size, VariantIdx}; @@ -90,11 +88,28 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' return false; } - for &(predicate, _span) in cx.tcx.explicit_item_bounds(def_id) { +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + for (predicate, _span) in cx.tcx.explicit_item_bounds(def_id).subst_identity_iter_copied() { +======= + for bound in cx.tcx.bound_explicit_item_bounds(def_id).transpose_iter() { +======= + for bound in cx.tcx.explicit_item_bounds(def_id).transpose_iter() { +>>>>>>> 097309c10 (add EarlyBinder to output of explicit_item_bounds; replace bound_explicit_item_bounds usages; remove bound_explicit_item_bounds query) + let (predicate, _span) = bound.map_bound(|b| *b).subst_identity(); +>>>>>>> afa28e630 (change usages of explicit_item_bounds to bound_explicit_item_bounds) +======= + for (predicate, _span) in cx.tcx.explicit_item_bounds(def_id).subst_identity_iter_copied() { +>>>>>>> 55d814633 (add subst_identity_iter and subst_identity_iter_copied methods on EarlyBinder; use this to simplify some EarlyBinder noise around explicit_item_bounds calls) match predicate.kind().skip_binder() { // For `impl Trait`, it will register a predicate of `T: Trait`, so we go through - // and check substituions to find `U`. + // and check substitutions to find `U`. +<<<<<<< HEAD + ty::ClauseKind::Trait(trait_predicate) => { +======= ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => { +>>>>>>> e4f5d83fa (Fixed formatting.) if trait_predicate .trait_ref .substs @@ -107,7 +122,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' }, // For `impl Trait`, it will register a predicate of `::Assoc = U`, // so we check the term for `U`. - ty::PredicateKind::Clause(ty::Clause::Projection(projection_predicate)) => { + ty::ClauseKind::Projection(projection_predicate) => { if let ty::TermKind::Ty(ty) = projection_predicate.term.unpack() { if contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen) { return true; @@ -226,7 +241,7 @@ pub fn implements_trait_with_env<'tcx>( ty_params: impl IntoIterator>>, ) -> bool { // Clippy shouldn't have infer types - assert!(!ty.needs_infer()); + assert!(!ty.has_infer()); let ty = tcx.erase_regions(ty); if ty.has_escaping_bound_vars() { @@ -267,8 +282,27 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { }, ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)), ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { - for (predicate, _) in cx.tcx.explicit_item_bounds(*def_id) { +<<<<<<< HEAD +<<<<<<< HEAD + for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() { +<<<<<<< HEAD +<<<<<<< HEAD +======= + for (predicate, _) in cx.tcx.bound_explicit_item_bounds(*def_id).skip_binder() { +>>>>>>> afa28e630 (change usages of explicit_item_bounds to bound_explicit_item_bounds) +======= + for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() { +>>>>>>> 097309c10 (add EarlyBinder to output of explicit_item_bounds; replace bound_explicit_item_bounds usages; remove bound_explicit_item_bounds query) + if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() { +======= + if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() { +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= + if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() { +======= if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() { +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) { return true; } @@ -277,7 +311,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { false }, ty::Dynamic(binder, _, _) => { - for predicate in binder.iter() { + for predicate in *binder { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() { if cx.tcx.has_attr(trait_ref.def_id, sym::must_use) { return true; @@ -563,7 +597,7 @@ fn is_uninit_value_valid_for_ty_fallback<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t } /// Gets an iterator over all predicates which apply to the given item. -pub fn all_predicates_of(tcx: TyCtxt<'_>, id: DefId) -> impl Iterator, Span)> { +pub fn all_predicates_of(tcx: TyCtxt<'_>, id: DefId) -> impl Iterator, Span)> { let mut next_id = Some(id); iter::from_fn(move || { next_id.take().map(|id| { @@ -665,7 +699,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option sig_from_bounds( cx, ty, - cx.tcx.item_bounds(def_id).subst(cx.tcx, substs), + cx.tcx.item_bounds(def_id).subst_iter(cx.tcx, substs), cx.tcx.opt_parent(def_id), ), ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)), @@ -698,7 +732,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option( cx: &LateContext<'tcx>, ty: Ty<'tcx>, - predicates: &'tcx [Predicate<'tcx>], + predicates: impl IntoIterator>, predicates_id: Option, ) -> Option> { let mut inputs = None; @@ -707,7 +741,7 @@ fn sig_from_bounds<'tcx>( for pred in predicates { match pred.kind().skip_binder() { - PredicateKind::Clause(ty::Clause::Trait(p)) + ty::ClauseKind::Trait(p) if (lang_items.fn_trait() == Some(p.def_id()) || lang_items.fn_mut_trait() == Some(p.def_id()) || lang_items.fn_once_trait() == Some(p.def_id())) @@ -720,7 +754,7 @@ fn sig_from_bounds<'tcx>( } inputs = Some(i); }, - PredicateKind::Clause(ty::Clause::Projection(p)) + ty::ClauseKind::Projection(p) if Some(p.projection_ty.def_id) == lang_items.fn_once_output() && p.projection_ty.self_ty() == ty => { if output.is_some() { @@ -743,11 +777,11 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option for (pred, _) in cx .tcx - .bound_explicit_item_bounds(ty.def_id) + .explicit_item_bounds(ty.def_id) .subst_iter_copied(cx.tcx, ty.substs) { match pred.kind().skip_binder() { - PredicateKind::Clause(ty::Clause::Trait(p)) + ty::ClauseKind::Trait(p) if (lang_items.fn_trait() == Some(p.def_id()) || lang_items.fn_mut_trait() == Some(p.def_id()) || lang_items.fn_once_trait() == Some(p.def_id())) => @@ -760,9 +794,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option } inputs = Some(i); }, - PredicateKind::Clause(ty::Clause::Projection(p)) - if Some(p.projection_ty.def_id) == lang_items.fn_once_output() => - { + ty::ClauseKind::Projection(p) if Some(p.projection_ty.def_id) == lang_items.fn_once_output() => { if output.is_some() { // Multiple different fn trait impls. Is this even allowed? return None; @@ -937,7 +969,7 @@ pub fn adt_and_variant_of_res<'tcx>(cx: &LateContext<'tcx>, res: Res) -> Option< } /// Checks if the type is a type parameter implementing `FnOnce`, but not `FnMut`. -pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tcx [Predicate<'_>]) -> bool { +pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tcx [ty::Clause<'_>]) -> bool { let ty::Param(ty) = *ty.kind() else { return false; }; @@ -950,7 +982,7 @@ pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tc predicates .iter() .try_fold(false, |found, p| { - if let PredicateKind::Clause(ty::Clause::Trait(p)) = p.kind().skip_binder() + if let ty::ClauseKind::Trait(p) = p.kind().skip_binder() && let ty::Param(self_ty) = p.trait_ref.self_ty().kind() && ty.index == self_ty.index { @@ -975,7 +1007,7 @@ pub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 { } match (cx.layout_of(ty).map(|layout| layout.size.bytes()), ty.kind()) { (Ok(size), _) => size, - (Err(_), ty::Tuple(list)) => list.as_substs().types().map(|t| approx_ty_size(cx, t)).sum(), + (Err(_), ty::Tuple(list)) => list.iter().map(|t| approx_ty_size(cx, t)).sum(), (Err(_), ty::Array(t, n)) => { n.try_eval_target_usize(cx.tcx, cx.param_env).unwrap_or_default() * approx_ty_size(cx, *t) }, @@ -1101,7 +1133,7 @@ pub fn make_projection<'tcx>( /// /// This function is for associated types which are "known" to be valid with the given /// substitutions, and as such, will only return `None` when debug assertions are disabled in order -/// to prevent ICE's. With debug assertions enabled this will check that that type normalization +/// to prevent ICE's. With debug assertions enabled this will check that type normalization /// succeeds as well as everything checked by `make_projection`. pub fn make_normalized_projection<'tcx>( tcx: TyCtxt<'tcx>, @@ -1126,7 +1158,7 @@ pub fn make_normalized_projection<'tcx>( ); return None; } - match tcx.try_normalize_erasing_regions(param_env, tcx.mk_projection(ty.def_id, ty.substs)) { + match tcx.try_normalize_erasing_regions(param_env, Ty::new_projection(tcx,ty.def_id, ty.substs)) { Ok(ty) => Some(ty), Err(e) => { debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}"); @@ -1180,3 +1212,55 @@ pub fn is_interior_mut_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { _ => false, } } + +pub fn make_normalized_projection_with_regions<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + container_id: DefId, + assoc_ty: Symbol, + substs: impl IntoIterator>>, +) -> Option> { + fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option> { + #[cfg(debug_assertions)] + if let Some((i, subst)) = ty + .substs + .iter() + .enumerate() + .find(|(_, subst)| subst.has_late_bound_regions()) + { + debug_assert!( + false, + "substs contain late-bound region at index `{i}` which can't be normalized.\n\ + use `TyCtxt::erase_late_bound_regions`\n\ + note: subst is `{subst:#?}`", + ); + return None; + } + let cause = rustc_middle::traits::ObligationCause::dummy(); + match tcx + .infer_ctxt() + .build() + .at(&cause, param_env) +<<<<<<< HEAD + .query_normalize(Ty::new_projection(tcx,ty.def_id, ty.substs)) +======= + .query_normalize(tcx.mk_projection(ty.def_id, ty.substs)) +>>>>>>> b6fa4d43d (Extend `explicit_iter_loop` to all types) + { + Ok(ty) => Some(ty.value), + Err(e) => { + debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}"); + None + }, + } + } + helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, substs)?) +} + +pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { + let cause = rustc_middle::traits::ObligationCause::dummy(); + match tcx.infer_ctxt().build().at(&cause, param_env).query_normalize(ty) { + Ok(ty) => ty.value, + Err(_) => ty, + } +} diff --git a/clippy_utils/src/usage.rs b/clippy_utils/src/usage.rs index ab3976a13bdb..efb23825abb9 100644 --- a/clippy_utils/src/usage.rs +++ b/clippy_utils/src/usage.rs @@ -1,16 +1,14 @@ -use crate as utils; use crate::visitors::{for_each_expr, for_each_expr_with_closures, Descend}; use core::ops::ControlFlow; -use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::HirIdSet; -use rustc_hir::{Expr, ExprKind, HirId, Node}; +use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, Node}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty; +use {crate as utils, rustc_hir as hir}; /// Returns a set of mutated local variable IDs, or `None` if mutations could not be determined. pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> Option { @@ -82,7 +80,7 @@ pub struct ParamBindingIdCollector { impl<'tcx> ParamBindingIdCollector { fn collect_binding_hir_ids(body: &'tcx hir::Body<'tcx>) -> Vec { let mut hir_ids: Vec = Vec::new(); - for param in body.params.iter() { + for param in body.params { let mut finder = ParamBindingIdCollector { binding_hir_ids: Vec::new(), }; diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs index 1dc19bac9844..8dafa723afa0 100644 --- a/clippy_utils/src/visitors.rs +++ b/clippy_utils/src/visitors.rs @@ -651,6 +651,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( // Either drops temporaries, jumps out of the current expression, or has no sub expression. ExprKind::DropTemps(_) | ExprKind::Ret(_) + | ExprKind::Become(_) | ExprKind::Break(..) | ExprKind::Yield(..) | ExprKind::Block(..) @@ -662,6 +663,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( | ExprKind::Path(_) | ExprKind::Continue(_) | ExprKind::InlineAsm(_) + | ExprKind::OffsetOf(..) | ExprKind::Err(_) => (), } ControlFlow::Continue(()) diff --git a/declare_clippy_lint/Cargo.toml b/declare_clippy_lint/Cargo.toml index bd26f4fc9139..6baf671ec19d 100644 --- a/declare_clippy_lint/Cargo.toml +++ b/declare_clippy_lint/Cargo.toml @@ -1,6 +1,10 @@ [package] name = "declare_clippy_lint" -version = "0.1.70" +<<<<<<< HEAD +version = "0.1.73" +======= +version = "0.1.71" +>>>>>>> e4f5d83fa (Fixed formatting.) edition = "2021" publish = false diff --git a/declare_clippy_lint/src/lib.rs b/declare_clippy_lint/src/lib.rs index 5232e4ab7d75..0057256f659b 100644 --- a/declare_clippy_lint/src/lib.rs +++ b/declare_clippy_lint/src/lib.rs @@ -85,8 +85,8 @@ impl Parse for ClippyLint { /// 2. The `LINT_NAME`. See [lint naming][lint_naming] on lint naming conventions. /// 3. The `lint_level`, which is a mapping from *one* of our lint groups to `Allow`, `Warn` or /// `Deny`. The lint level here has nothing to do with what lint groups the lint is a part of. -/// 4. The `description` that contains a short explanation on what's wrong with code where the -/// lint is triggered. +/// 4. The `description` that contains a short explanation on what's wrong with code where the lint +/// is triggered. /// /// Currently the categories `style`, `correctness`, `suspicious`, `complexity` and `perf` are /// enabled by default. As said in the README.md of this repository, if the lint level mapping diff --git a/lintcheck/Cargo.toml b/lintcheck/Cargo.toml index 27d32f390035..a828d1237046 100644 --- a/lintcheck/Cargo.toml +++ b/lintcheck/Cargo.toml @@ -22,7 +22,7 @@ rayon = "1.5.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.85" tar = "0.4" -toml = "0.5" +toml = "0.7.3" ureq = "2.2" walkdir = "2.3" diff --git a/lintcheck/README.md b/lintcheck/README.md index faf3ce9093a2..37cc04538094 100644 --- a/lintcheck/README.md +++ b/lintcheck/README.md @@ -79,9 +79,11 @@ is explicitly specified in the options. ### Fix mode You can run `cargo lintcheck --fix` which will run Clippy with `--fix` and -print a warning if Clippy's suggestions fail to apply (if the resulting code does not build). +print a warning if Clippy's suggestions fail to apply (if the resulting code does not build). This lets us spot bad suggestions or false positives automatically in some cases. +> Note: Fix mode implies `--all-targets`, so it can fix as much code as it can. + Please note that the target dir should be cleaned afterwards since clippy will modify the downloaded sources which can lead to unexpected results when running lintcheck again afterwards. diff --git a/lintcheck/src/config.rs b/lintcheck/src/config.rs index 3f01e9bb0a71..e678d40795ee 100644 --- a/lintcheck/src/config.rs +++ b/lintcheck/src/config.rs @@ -1,5 +1,6 @@ use clap::Parser; -use std::{num::NonZeroUsize, path::PathBuf}; +use std::num::NonZeroUsize; +use std::path::PathBuf; #[derive(Clone, Debug, Parser)] pub(crate) struct LintcheckConfig { diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index 23c852980275..3a022b343a43 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -15,16 +15,14 @@ use crate::config::LintcheckConfig; use crate::recursive::LintcheckServer; use std::collections::{HashMap, HashSet}; -use std::env; use std::env::consts::EXE_SUFFIX; use std::fmt::{self, Write as _}; -use std::fs; use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; use std::process::Command; use std::sync::atomic::{AtomicUsize, Ordering}; -use std::thread; use std::time::Duration; +use std::{env, fs, thread}; use cargo_metadata::diagnostic::{Diagnostic, DiagnosticLevel}; use cargo_metadata::Message; @@ -421,7 +419,7 @@ impl Crate { { let subcrate = &stderr[63..]; println!( - "ERROR: failed to apply some suggetion to {} / to (sub)crate {subcrate}", + "ERROR: failed to apply some suggestion to {} / to (sub)crate {subcrate}", self.name ); } @@ -474,7 +472,7 @@ fn read_crates(toml_path: &Path) -> (Vec, RecursiveOptions) { }); } else if let Some(ref versions) = tk.versions { // if we have multiple versions, save each one - for ver in versions.iter() { + for ver in versions { crate_sources.push(CrateSource::CratesIo { name: tk.name.clone(), version: ver.to_string(), diff --git a/lintcheck/src/recursive.rs b/lintcheck/src/recursive.rs index 49072e65192f..994fa3c3b239 100644 --- a/lintcheck/src/recursive.rs +++ b/lintcheck/src/recursive.rs @@ -3,8 +3,7 @@ //! [`LintcheckServer`] to ask if it should be skipped, and if not sends the stderr of running //! clippy on the crate to the server -use crate::ClippyWarning; -use crate::RecursiveOptions; +use crate::{ClippyWarning, RecursiveOptions}; use std::collections::HashSet; use std::io::{BufRead, BufReader, Read, Write}; diff --git a/rust-toolchain b/rust-toolchain index 91e8ccea1f43..ceb2fc79cc97 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,47 @@ [toolchain] +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +channel = "nightly-2023-04-23" +======= +channel = "nightly-2023-05-05" +>>>>>>> 79656cc95 (Bump nightly version -> 2023-05-05) +======= channel = "nightly-2023-04-06" +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +channel = "nightly-2023-04-23" +>>>>>>> d5a2c2ba7 (Bump nightly version -> 2023-04-23) +======= +channel = "nightly-2023-05-05" +>>>>>>> 79656cc95 (Bump nightly version -> 2023-05-05) +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +channel = "nightly-2023-06-29" +======= +channel = "nightly-2023-05-20" +>>>>>>> 2e95a4fd4 (Bump nightly version -> 2023-05-20) +======= +channel = "nightly-2023-06-02" +>>>>>>> dfdc25834 (Bump nightly version -> 2023-06-02) +======= +channel = "nightly-2023-06-29" +>>>>>>> 30d08d35f (Bump nightly version -> 2023-06-29) +======= +channel = "nightly-2023-07-14" +>>>>>>> 753c30f34 (Bump nightly version -> 2023-07-14) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +channel = "nightly-2023-04-23" +======= +channel = "nightly-2023-05-05" +>>>>>>> 79656cc95 (Bump nightly version -> 2023-05-05) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] diff --git a/rustfmt.toml b/rustfmt.toml index 10d39762043e..4248f42f654b 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -4,4 +4,6 @@ match_block_trailing_comma = true wrap_comments = true edition = "2021" error_on_line_overflow = true +imports_granularity = "Module" version = "Two" +ignore = ["tests/ui/crashes/ice-10912.rs"] diff --git a/src/driver.rs b/src/driver.rs index 718bc41fb992..ee17feed77a0 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -11,22 +11,20 @@ // FIXME: switch to something more ergonomic here, once available. // (Currently there is no way to opt into sysroot crates without `extern crate`.) extern crate rustc_driver; -extern crate rustc_errors; extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; use rustc_interface::interface; +use rustc_session::config::ErrorOutputType; use rustc_session::parse::ParseSess; +use rustc_session::EarlyErrorHandler; use rustc_span::symbol::Symbol; -use std::borrow::Cow; use std::env; use std::ops::Deref; -use std::panic; use std::path::Path; use std::process::exit; -use std::sync::LazyLock; /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If /// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`. @@ -74,7 +72,7 @@ fn track_clippy_args(parse_sess: &mut ParseSess, args_env_var: &Option) /// Track files that may be accessed at runtime in `file_depinfo` so that cargo will re-run clippy /// when any of them are modified -fn track_files(parse_sess: &mut ParseSess, conf_path_string: Option) { +fn track_files(parse_sess: &mut ParseSess) { let file_depinfo = parse_sess.file_depinfo.get_mut(); // Used by `clippy::cargo` lints and to determine the MSRV. `cargo clippy` executes `clippy-driver` @@ -83,10 +81,7 @@ fn track_files(parse_sess: &mut ParseSess, conf_path_string: Option) { file_depinfo.insert(Symbol::intern("Cargo.toml")); } - // `clippy.toml` - if let Some(path) = conf_path_string { - file_depinfo.insert(Symbol::intern(&path)); - } + // `clippy.toml` will be automatically tracked as it's loaded with `sess.source_map().load_file()` // During development track the `clippy-driver` executable so that cargo will re-run clippy whenever // it is rebuilt @@ -130,17 +125,18 @@ impl rustc_driver::Callbacks for ClippyCallbacks { #[allow(rustc::bad_opt_access)] fn config(&mut self, config: &mut interface::Config) { let conf_path = clippy_lints::lookup_conf_file(); - let conf_path_string = if let Ok((Some(path), _)) = &conf_path { - path.to_str().map(String::from) - } else { - None - }; - let previous = config.register_lints.take(); let clippy_args_var = self.clippy_args_var.take(); config.parse_sess_created = Some(Box::new(move |parse_sess| { track_clippy_args(parse_sess, &clippy_args_var); - track_files(parse_sess, conf_path_string); + track_files(parse_sess); + + // Trigger a rebuild if CLIPPY_CONF_DIR changes. The value must be a valid string so + // changes between dirs that are invalid UTF-8 will not trigger rebuilds + parse_sess.env_depinfo.get_mut().insert(( + Symbol::intern("CLIPPY_CONF_DIR"), + env::var("CLIPPY_CONF_DIR").ok().map(|dir| Symbol::intern(&dir)), + )); })); config.register_lints = Some(Box::new(move |sess, lint_store| { // technically we're ~guaranteed that this is none but might as well call anything that @@ -160,6 +156,9 @@ impl rustc_driver::Callbacks for ClippyCallbacks { // MIR passes can be enabled / disabled separately, we should figure out, what passes to // use for Clippy. config.opts.unstable_opts.mir_opt_level = Some(0); + + // Disable flattening and inlining of format_args!(), so the HIR matches with the AST. + config.opts.unstable_opts.flatten_format_args = false; } } @@ -195,66 +194,20 @@ You can use tool lints to allow or deny lints from your code, eg.: const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new"; -type PanicCallback = dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static; -static ICE_HOOK: LazyLock> = LazyLock::new(|| { - let hook = panic::take_hook(); - panic::set_hook(Box::new(|info| report_clippy_ice(info, BUG_REPORT_URL))); - hook -}); - -fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { - // Invoke our ICE handler, which prints the actual panic message and optionally a backtrace - (*ICE_HOOK)(info); - - // Separate the output with an empty line - eprintln!(); - - let fallback_bundle = rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false); - let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( - rustc_errors::ColorConfig::Auto, - None, - None, - fallback_bundle, - false, - false, - None, - false, - false, - rustc_errors::TerminalUrl::No, - )); - let handler = rustc_errors::Handler::with_emitter(true, None, emitter); - - // a .span_bug or .bug call has already printed what - // it wants to print. - if !info.payload().is::() { - let mut d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic"); - handler.emit_diagnostic(&mut d); - } - - let version_info = rustc_tools_util::get_version_info!(); - - let xs: Vec> = vec![ - "the compiler unexpectedly panicked. this is a bug.".into(), - format!("we would appreciate a bug report: {bug_report_url}").into(), - format!("Clippy version: {version_info}").into(), - ]; - - for note in &xs { - handler.note_without_error(note.as_ref()); - } - - // If backtraces are enabled, also print the query stack - let backtrace = env::var_os("RUST_BACKTRACE").map_or(false, |x| &x != "0"); +#[allow(clippy::too_many_lines)] +pub fn main() { + let handler = EarlyErrorHandler::new(ErrorOutputType::default()); - let num_frames = if backtrace { None } else { Some(2) }; + rustc_driver::init_rustc_env_logger(&handler); - interface::try_print_query_stack(&handler, num_frames); -} + rustc_driver::install_ice_hook(BUG_REPORT_URL, |handler| { + // FIXME: this macro calls unwrap internally but is called in a panicking context! It's not + // as simple as moving the call from the hook to main, because `install_ice_hook` doesn't + // accept a generic closure. + let version_info = rustc_tools_util::get_version_info!(); + handler.note_without_error(format!("Clippy version: {version_info}")); + }); -#[allow(clippy::too_many_lines)] -pub fn main() { - rustc_driver::init_rustc_env_logger(); - LazyLock::force(&ICE_HOOK); exit(rustc_driver::catch_with_exit_code(move || { let mut orig_args: Vec = env::args().collect(); let has_sysroot_arg = arg_value(&orig_args, "--sysroot", |_| true).is_some(); diff --git a/src/main.rs b/src/main.rs index c5e9b96cf3fc..5ecce44148a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,14 +6,22 @@ use std::env; use std::path::PathBuf; use std::process::{self, Command}; -const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code. +<<<<<<< HEAD +<<<<<<< HEAD +const CARGO_CLIPPY_HELP: &str = "Checks a package to catch common mistakes and improve your Rust code. +======= +const CARGO_CLIPPY_HELP: &str = r"Checks a package to catch common mistakes and improve your Rust code. +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= +const CARGO_CLIPPY_HELP: &str = "Checks a package to catch common mistakes and improve your Rust code. +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) Usage: cargo clippy [options] [--] [...] Common options: --no-deps Run Clippy only on the given crate, without linting the dependencies - --fix Automatically apply lint suggestions. This flag implies `--no-deps` + --fix Automatically apply lint suggestions. This flag implies `--no-deps` and `--all-targets` -h, --help Print this message -V, --version Print version info and exit --explain LINT Print the documentation for a given lint @@ -31,7 +39,7 @@ with: You can use tool lints to allow or deny lints from your code, e.g.: #[allow(clippy::needless_lifetimes)] -"#; +"; fn show_help() { println!("{CARGO_CLIPPY_HELP}"); @@ -57,7 +65,9 @@ pub fn main() { if let Some(pos) = env::args().position(|a| a == "--explain") { if let Some(mut lint) = env::args().nth(pos + 1) { lint.make_ascii_lowercase(); - clippy_lints::explain(&lint.strip_prefix("clippy::").unwrap_or(&lint).replace('-', "_")); + process::exit(clippy_lints::explain( + &lint.strip_prefix("clippy::").unwrap_or(&lint).replace('-', "_"), + )); } else { show_help(); } diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 57890ff31737..44516806076e 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -3,23 +3,32 @@ #![feature(is_sorted)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] +#![allow(unused_extern_crates)] -use compiletest_rs as compiletest; -use compiletest_rs::common::Mode as TestMode; +use compiletest::{status_emitter, CommandBuilder}; +use ui_test as compiletest; +use ui_test::Mode as TestMode; -use std::collections::HashMap; +use std::collections::BTreeMap; use std::env::{self, remove_var, set_var, var_os}; use std::ffi::{OsStr, OsString}; use std::fs; -use std::io; use std::path::{Path, PathBuf}; use std::sync::LazyLock; use test_utils::IS_RUSTC_TEST_SUITE; -mod test_utils; - -// whether to run internal tests or not -const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal"); +// Test dependencies may need an `extern crate` here to ensure that they show up +// in the depinfo file (otherwise cargo thinks they are unused) +extern crate clippy_lints; +extern crate clippy_utils; +extern crate derive_new; +extern crate futures; +extern crate if_chain; +extern crate itertools; +extern crate parking_lot; +extern crate quote; +extern crate syn; +extern crate tokio; /// All crates used in UI tests are listed here static TEST_DEPENDENCIES: &[&str] = &[ @@ -29,41 +38,15 @@ static TEST_DEPENDENCIES: &[&str] = &[ "futures", "if_chain", "itertools", + "parking_lot", "quote", "regex", - "serde", "serde_derive", + "serde", "syn", "tokio", - "parking_lot", - "rustc_semver", ]; -// Test dependencies may need an `extern crate` here to ensure that they show up -// in the depinfo file (otherwise cargo thinks they are unused) -#[allow(unused_extern_crates)] -extern crate clippy_lints; -#[allow(unused_extern_crates)] -extern crate clippy_utils; -#[allow(unused_extern_crates)] -extern crate derive_new; -#[allow(unused_extern_crates)] -extern crate futures; -#[allow(unused_extern_crates)] -extern crate if_chain; -#[allow(unused_extern_crates)] -extern crate itertools; -#[allow(unused_extern_crates)] -extern crate parking_lot; -#[allow(unused_extern_crates)] -extern crate quote; -#[allow(unused_extern_crates)] -extern crate rustc_semver; -#[allow(unused_extern_crates)] -extern crate syn; -#[allow(unused_extern_crates)] -extern crate tokio; - /// Produces a string with an `--extern` flag for all UI test crate /// dependencies. /// @@ -72,13 +55,13 @@ extern crate tokio; /// dependencies must be added to Cargo.toml at the project root. Test /// dependencies that are not *directly* used by this test module require an /// `extern crate` declaration. -static EXTERN_FLAGS: LazyLock = LazyLock::new(|| { +static EXTERN_FLAGS: LazyLock> = LazyLock::new(|| { let current_exe_depinfo = { let mut path = env::current_exe().unwrap(); path.set_extension("d"); fs::read_to_string(path).unwrap() }; - let mut crates: HashMap<&str, &str> = HashMap::with_capacity(TEST_DEPENDENCIES.len()); + let mut crates = BTreeMap::<&str, &str>::new(); for line in current_exe_depinfo.lines() { // each dependency is expected to have a Makefile rule like `/path/to/crate-hash.rlib:` let parse_name_path = || { @@ -118,45 +101,89 @@ static EXTERN_FLAGS: LazyLock = LazyLock::new(|| { ); crates .into_iter() - .map(|(name, path)| format!(" --extern {name}={path}")) + .map(|(name, path)| format!("--extern={name}={path}")) .collect() }); +mod test_utils; + +// whether to run internal tests or not +const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal"); + fn base_config(test_dir: &str) -> compiletest::Config { let mut config = compiletest::Config { +<<<<<<< HEAD + mode: TestMode::Yolo, + stderr_filters: vec![], + stdout_filters: vec![], +<<<<<<< HEAD +<<<<<<< HEAD + output_conflict_handling: if var_os("BLESS").is_some() || env::args().any(|arg| arg == "--bless") { +======= + output_conflict_handling: if std::env::args().any(|arg| arg == "--bless") { +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) +======= + output_conflict_handling: if var_os("BLESS").is_some() || env::args().any(|arg| arg == "--bless") { +>>>>>>> 76de5560f (Add BLESS for compile-test and some cleanup) + compiletest::OutputConflictHandling::Bless + } else { + compiletest::OutputConflictHandling::Error("cargo test -- -- --bless".into()) + }, + target: None, +<<<<<<< HEAD + out_dir: PathBuf::from(std::env::var_os("CARGO_TARGET_DIR").unwrap_or("target".into())).join("ui_test"), +======= + out_dir: "target/ui_test".into(), +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) + ..compiletest::Config::rustc(Path::new("tests").join(test_dir)) +======= edition: Some("2021".into()), mode: TestMode::Ui, + strict_headers: true, ..Default::default() +>>>>>>> e4f5d83fa (Fixed formatting.) }; - if let Ok(filters) = env::var("TESTNAME") { - config.filters = filters.split(',').map(ToString::to_string).collect(); - } - - if let Some(path) = option_env!("RUSTC_LIB_PATH") { - let path = PathBuf::from(path); - config.run_lib_path = path.clone(); - config.compile_lib_path = path; + if let Some(_path) = option_env!("RUSTC_LIB_PATH") { + //let path = PathBuf::from(path); + //config.run_lib_path = path.clone(); + //config.compile_lib_path = path; } let current_exe_path = env::current_exe().unwrap(); let deps_path = current_exe_path.parent().unwrap(); let profile_path = deps_path.parent().unwrap(); - // Using `-L dependency={}` enforces that external dependencies are added with `--extern`. - // This is valuable because a) it allows us to monitor what external dependencies are used - // and b) it ensures that conflicting rlibs are resolved properly. - let host_libs = option_env!("HOST_LIBS") - .map(|p| format!(" -L dependency={}", Path::new(p).join("deps").display())) - .unwrap_or_default(); - config.target_rustcflags = Some(format!( - "--emit=metadata -Dwarnings -Zui-testing -L dependency={}{host_libs}{}", - deps_path.display(), - &*EXTERN_FLAGS, - )); - - config.src_base = Path::new("tests").join(test_dir); - config.build_base = profile_path.join("test").join(test_dir); - config.rustc_path = profile_path.join(if cfg!(windows) { + config.program.args.extend( + [ + "--emit=metadata", + "-Aunused", + "-Zui-testing", + "-Dwarnings", + &format!("-Ldependency={}", deps_path.display()), + ] + .map(OsString::from), + ); + + config.program.args.extend(EXTERN_FLAGS.iter().map(OsString::from)); + + if let Some(host_libs) = option_env!("HOST_LIBS") { + let dep = format!("-Ldependency={}", Path::new(host_libs).join("deps").display()); + config.program.args.push(dep.into()); + } + + // Normalize away slashes in windows paths. +<<<<<<< HEAD +<<<<<<< HEAD + config.stderr_filter(r"\\", "/"); +======= + config.stderr_filter(r#"\\"#, "/"); +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) +======= + config.stderr_filter(r"\\", "/"); +>>>>>>> 8cb6c8699 (change category and refactor) + + //config.build_base = profile_path.join("test").join(test_dir); + config.program.program = profile_path.join(if cfg!(windows) { "clippy-driver.exe" } else { "clippy-driver" @@ -164,9 +191,31 @@ fn base_config(test_dir: &str) -> compiletest::Config { config } +fn test_filter() -> Box bool> { + if let Ok(filters) = env::var("TESTNAME") { + let filters: Vec<_> = filters.split(',').map(ToString::to_string).collect(); +<<<<<<< HEAD +<<<<<<< HEAD + Box::new(move |path| filters.iter().any(|f| path.to_string_lossy().contains(f))) +======= + Box::new(move |path| { + filters.is_empty() + || filters + .iter() + .any(|f| path.file_stem().map_or(false, |stem| stem == f.as_str())) + }) +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) +======= + Box::new(move |path| filters.iter().any(|f| path.to_string_lossy().contains(f))) +>>>>>>> 8647e2915 (Use substring matching for TESTNAME) + } else { + Box::new(|_| true) + } +} + fn run_ui() { - let mut config = base_config("ui"); - config.rustfix_coverage = true; + let config = base_config("ui"); + //config.rustfix_coverage = true; // use tests/clippy.toml let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap()); let _threads = VarGuard::set( @@ -178,7 +227,19 @@ fn run_ui() { .to_string() }), ); - compiletest::run_tests(&config); + eprintln!(" Compiler: {}", config.program.display()); + + let name = config.root_dir.display().to_string(); + + let test_filter = test_filter(); + + compiletest::run_tests_generic( + config, + move |path| compiletest::default_file_filter(path) && test_filter(path), + compiletest::default_per_file_config, + (status_emitter::Text, status_emitter::Gha:: { name }), + ) + .unwrap(); check_rustfix_coverage(); } @@ -188,176 +249,179 @@ fn run_internal_tests() { return; } let config = base_config("ui-internal"); - compiletest::run_tests(&config); + compiletest::run_tests(config).unwrap(); } fn run_ui_toml() { - fn run_tests(config: &compiletest::Config, mut tests: Vec) -> Result { - let mut result = true; - let opts = compiletest::test_opts(config); - for dir in fs::read_dir(&config.src_base)? { - let dir = dir?; - if !dir.file_type()?.is_dir() { - continue; - } - let dir_path = dir.path(); - let _g = VarGuard::set("CARGO_MANIFEST_DIR", &dir_path); - for file in fs::read_dir(&dir_path)? { - let file = file?; - let file_path = file.path(); - if file.file_type()?.is_dir() { - continue; - } - if file_path.extension() != Some(OsStr::new("rs")) { - continue; - } - let paths = compiletest::common::TestPaths { - file: file_path, - base: config.src_base.clone(), - relative_dir: dir_path.file_name().unwrap().into(), - }; - let test_name = compiletest::make_test_name(config, &paths); - let index = tests - .iter() - .position(|test| test.desc.name == test_name) - .expect("The test should be in there"); - result &= tester::run_tests_console(&opts, vec![tests.swap_remove(index)])?; - } - } - Ok(result) - } - let mut config = base_config("ui-toml"); - config.src_base = config.src_base.canonicalize().unwrap(); - let tests = compiletest::make_tests(&config); + config.stderr_filter( + ®ex::escape( +<<<<<<< HEAD + &fs::canonicalize("tests") +======= + &std::path::Path::new(file!()) + .parent() + .unwrap() + .canonicalize() +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) + .unwrap() + .parent() + .unwrap() + .display() + .to_string() + .replace('\\', "/"), + ), + "$$DIR", + ); + + let name = config.root_dir.display().to_string(); + + let test_filter = test_filter(); - let res = run_tests(&config, tests); - match res { - Ok(true) => {}, - Ok(false) => panic!("Some tests failed"), - Err(e) => { - panic!("I/O failure during tests: {e:?}"); + ui_test::run_tests_generic( + config, + |path| test_filter(path) && path.extension() == Some("rs".as_ref()), + |config, path| { + let mut config = config.clone(); + config + .program + .envs + .push(("CLIPPY_CONF_DIR".into(), Some(path.parent().unwrap().into()))); + Some(config) }, - } + (status_emitter::Text, status_emitter::Gha:: { name }), + ) + .unwrap(); } fn run_ui_cargo() { - fn run_tests( - config: &compiletest::Config, - filters: &[String], - mut tests: Vec, - ) -> Result { - let mut result = true; - let opts = compiletest::test_opts(config); - - for dir in fs::read_dir(&config.src_base)? { - let dir = dir?; - if !dir.file_type()?.is_dir() { - continue; - } - - // Use the filter if provided - let dir_path = dir.path(); - for filter in filters { - if !dir_path.ends_with(filter) { - continue; - } - } - - for case in fs::read_dir(&dir_path)? { - let case = case?; - if !case.file_type()?.is_dir() { - continue; - } - - let src_path = case.path().join("src"); - - // When switching between branches, if the previous branch had a test - // that the current branch does not have, the directory is not removed - // because an ignored Cargo.lock file exists. - if !src_path.exists() { - continue; - } - - env::set_current_dir(&src_path)?; - - let cargo_toml_path = case.path().join("Cargo.toml"); - let cargo_content = fs::read(cargo_toml_path)?; - let cargo_parsed: toml::Value = toml::from_str( - std::str::from_utf8(&cargo_content).expect("`Cargo.toml` is not a valid utf-8 file!"), - ) - .expect("Can't parse `Cargo.toml`"); - - let _g = VarGuard::set("CARGO_MANIFEST_DIR", case.path()); - let _h = VarGuard::set( - "CARGO_PKG_RUST_VERSION", - cargo_parsed - .get("package") - .and_then(|p| p.get("rust-version")) - .and_then(toml::Value::as_str) - .unwrap_or(""), - ); - - for file in fs::read_dir(&src_path)? { - let file = file?; - if file.file_type()?.is_dir() { - continue; - } - - // Search for the main file to avoid running a test for each file in the project - let file_path = file.path(); - match file_path.file_name().and_then(OsStr::to_str) { - Some("main.rs") => {}, - _ => continue, - } - let _g = VarGuard::set("CLIPPY_CONF_DIR", case.path()); - let paths = compiletest::common::TestPaths { - file: file_path, - base: config.src_base.clone(), - relative_dir: src_path.strip_prefix(&config.src_base).unwrap().into(), - }; - let test_name = compiletest::make_test_name(config, &paths); - let index = tests - .iter() - .position(|test| test.desc.name == test_name) - .expect("The test should be in there"); - result &= tester::run_tests_console(&opts, vec![tests.swap_remove(index)])?; - } - } - } - Ok(result) - } - if IS_RUSTC_TEST_SUITE { return; } let mut config = base_config("ui-cargo"); - config.src_base = config.src_base.canonicalize().unwrap(); +<<<<<<< HEAD +<<<<<<< HEAD + config.program.input_file_flag = CommandBuilder::cargo().input_file_flag; + config.program.out_dir_flag = CommandBuilder::cargo().out_dir_flag; +======= + config.program = CommandBuilder::cargo(); +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) +======= + config.program.input_file_flag = CommandBuilder::cargo().input_file_flag; + config.program.out_dir_flag = CommandBuilder::cargo().out_dir_flag; +>>>>>>> 0a87ce866 (Find the right `cargo-clippy` binary in CI) + config.program.args = vec!["clippy".into(), "--color".into(), "never".into(), "--quiet".into()]; + config + .program + .envs + .push(("RUSTFLAGS".into(), Some("-Dwarnings".into()))); + // We need to do this while we still have a rustc in the `program` field. + config.fill_host_and_target().unwrap(); + config.program.program.set_file_name(if cfg!(windows) { + "cargo-clippy.exe" + } else { + "cargo-clippy" + }); + config.edition = None; + + config.stderr_filter( + ®ex::escape( +<<<<<<< HEAD + &fs::canonicalize("tests") +======= + &std::path::Path::new(file!()) + .parent() + .unwrap() + .canonicalize() +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) + .unwrap() + .parent() + .unwrap() + .display() + .to_string() + .replace('\\', "/"), + ), + "$$DIR", + ); - let tests = compiletest::make_tests(&config); + let name = config.root_dir.display().to_string(); - let current_dir = env::current_dir().unwrap(); - let res = run_tests(&config, &config.filters, tests); - env::set_current_dir(current_dir).unwrap(); + let test_filter = test_filter(); - match res { - Ok(true) => {}, - Ok(false) => panic!("Some tests failed"), - Err(e) => { - panic!("I/O failure during tests: {e:?}"); + ui_test::run_tests_generic( + config, + |path| test_filter(path) && path.ends_with("Cargo.toml"), + |config, path| { + let mut config = config.clone(); + config.out_dir = PathBuf::from("target/ui_test_cargo/").join(path.parent().unwrap()); + Some(config) }, - } + (status_emitter::Text, status_emitter::Gha:: { name }), + ) + .unwrap(); } -#[test] -fn compile_test() { +fn main() { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 95ab05de2 (Fix compile-test under cargo nextest) + // Support being run by cargo nextest - https://nexte.st/book/custom-test-harnesses.html + if env::args().any(|arg| arg == "--list") { + if !env::args().any(|arg| arg == "--ignored") { + println!("compile_test: test"); + } + + return; + } + +<<<<<<< HEAD +======= +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) +======= +>>>>>>> 95ab05de2 (Fix compile-test under cargo nextest) set_var("CLIPPY_DISABLE_DOCS_LINKS", "true"); - run_ui(); - run_ui_toml(); - run_ui_cargo(); - run_internal_tests(); + // The SPEEDTEST_* env variables can be used to check Clippy's performance on your PR. It runs the + // affected test 1000 times and gets the average. + if let Ok(speedtest) = std::env::var("SPEEDTEST") { + println!("----------- STARTING SPEEDTEST -----------"); + let f = match speedtest.as_str() { + "ui" => run_ui as fn(), + "cargo" => run_ui_cargo as fn(), + "toml" => run_ui_toml as fn(), + "internal" => run_internal_tests as fn(), + "rustfix-coverage-known-exceptions-accuracy" => rustfix_coverage_known_exceptions_accuracy as fn(), + "ui-cargo-toml-metadata" => ui_cargo_toml_metadata as fn(), + + _ => panic!("unknown speedtest: {speedtest} || accepted speedtests are: [ui, cargo, toml, internal]"), + }; + + let iterations; + if let Ok(iterations_str) = std::env::var("SPEEDTEST_ITERATIONS") { + iterations = iterations_str + .parse::() + .unwrap_or_else(|_| panic!("Couldn't parse `{iterations_str}`, please use a valid u64")); + } else { + iterations = 1000; + } + + let mut sum = 0; + for _ in 0..iterations { + let start = std::time::Instant::now(); + f(); + sum += start.elapsed().as_millis(); + } + println!("average {} time: {} millis.", speedtest.to_uppercase(), sum / 1000); + } else { + run_ui(); + run_ui_toml(); + run_ui_cargo(); + run_internal_tests(); + rustfix_coverage_known_exceptions_accuracy(); + ui_cargo_toml_metadata(); + } } const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[ @@ -383,7 +447,6 @@ const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[ "needless_for_each_unfixable.rs", "nonminimal_bool.rs", "print_literal.rs", - "print_with_newline.rs", "redundant_static_lifetimes_multiple.rs", "ref_binding_to_reference.rs", "repl_uninit.rs", @@ -398,7 +461,6 @@ const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[ "unnecessary_lazy_eval_unfixable.rs", "write_literal.rs", "write_literal_2.rs", - "write_with_newline.rs", ]; fn check_rustfix_coverage() { @@ -424,32 +486,29 @@ fn check_rustfix_coverage() { .binary_search_by_key(&filename, Path::new) .is_ok(), "`{rs_file}` runs `MachineApplicable` diagnostics but is missing a `run-rustfix` annotation. \ - Please either add `// run-rustfix` at the top of the file or add the file to \ + Please either add `//@run-rustfix` at the top of the file or add the file to \ `RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS` in `tests/compile-test.rs`.", ); } } } -#[test] fn rustfix_coverage_known_exceptions_accuracy() { for filename in RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS { let rs_path = Path::new("tests/ui").join(filename); - assert!( - rs_path.exists(), - "`{}` does not exist", - rs_path.strip_prefix(env!("CARGO_MANIFEST_DIR")).unwrap().display() - ); + assert!(rs_path.exists(), "`{}` does not exist", rs_path.display()); let fixed_path = rs_path.with_extension("fixed"); - assert!( - !fixed_path.exists(), - "`{}` exists", - fixed_path.strip_prefix(env!("CARGO_MANIFEST_DIR")).unwrap().display() - ); +<<<<<<< HEAD +<<<<<<< HEAD +======= + println!("{}", fixed_path.display()); +>>>>>>> 514b6d04b (Port clippy away from compiletest to ui_test) +======= +>>>>>>> 76de5560f (Add BLESS for compile-test and some cleanup) + assert!(!fixed_path.exists(), "`{}` exists", fixed_path.display()); } } -#[test] fn ui_cargo_toml_metadata() { let ui_cargo_path = Path::new("tests/ui-cargo"); let cargo_common_metadata_path = ui_cargo_path.join("cargo_common_metadata"); diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 68a878e9a3d3..afde31face11 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -39,7 +39,7 @@ fn dogfood_clippy() { assert!( failed_packages.is_empty(), "Dogfood failed for packages `{}`", - failed_packages.iter().format(", "), + failed_packages.iter().join(", "), ); } diff --git a/tests/headers.rs b/tests/headers.rs new file mode 100644 index 000000000000..1d1e566cbf6f --- /dev/null +++ b/tests/headers.rs @@ -0,0 +1,29 @@ +use regex::Regex; +use std::fs; +use walkdir::WalkDir; + +#[test] +fn old_test_headers() { + let old_headers = Regex::new( + r"^//( ?\[\w+\])? ?((check|build|run|ignore|aux|only|needs|rustc|unset|no|normalize|run|compile)-|edition|incremental|revisions).*", + ) + .unwrap(); + let mut failed = false; + + for entry in WalkDir::new("tests") { + let entry = entry.unwrap(); + if !entry.file_type().is_file() { + continue; + } + + let file = fs::read_to_string(entry.path()).unwrap(); + + if let Some(header) = old_headers.find(&file) { + println!("Found header `{}` in {}", header.as_str(), entry.path().display()); + + failed = true; + } + } + + assert!(!failed, "use `//@foo` style test headers instead"); +} diff --git a/tests/lint_message_convention.rs b/tests/lint_message_convention.rs index 8feea800fdbe..98019c755276 100644 --- a/tests/lint_message_convention.rs +++ b/tests/lint_message_convention.rs @@ -18,18 +18,20 @@ impl Message { fn new(path: PathBuf) -> Self { // we don't want the first letter after "error: ", "help: " ... to be capitalized // also no punctuation (except for "?" ?) at the end of a line + // Prefer "try" over "try this". static REGEX_SET: LazyLock = LazyLock::new(|| { RegexSet::new([ - r"error: [A-Z]", - r"help: [A-Z]", - r"warning: [A-Z]", - r"note: [A-Z]", - r"try this: [A-Z]", - r"error: .*[.!]$", - r"help: .*[.!]$", - r"warning: .*[.!]$", - r"note: .*[.!]$", - r"try this: .*[.!]$", + "error: [A-Z]", + "help: [A-Z]", + "warning: [A-Z]", + "note: [A-Z]", + "try: [A-Z]", + "error: .*[.!]$", + "help: .*[.!]$", + "warning: .*[.!]$", + "note: .*[.!]$", + "try: .*[.!]$", + "try this", ]) .unwrap() }); @@ -39,11 +41,11 @@ impl Message { static EXCEPTIONS_SET: LazyLock = LazyLock::new(|| { RegexSet::new([ r"\.\.\.$", - r".*C-like enum variant discriminant is not portable to 32-bit targets", - r".*Intel x86 assembly syntax used", - r".*AT&T x86 assembly syntax used", - r"note: Clippy version: .*", - r"the compiler unexpectedly panicked. this is a bug.", + ".*C-like enum variant discriminant is not portable to 32-bit targets", + ".*Intel x86 assembly syntax used", + ".*AT&T x86 assembly syntax used", + "note: Clippy version: .*", + "the compiler unexpectedly panicked. this is a bug.", ]) .unwrap() }); diff --git a/tests/missing-test-files.rs b/tests/missing-test-files.rs index caedd5d76cd6..0d35a22cd9a4 100644 --- a/tests/missing-test-files.rs +++ b/tests/missing-test-files.rs @@ -41,8 +41,8 @@ fn explore_directory(dir: &Path) -> Vec { x.path().extension().and_then(OsStr::to_str), y.path().extension().and_then(OsStr::to_str), ) { - (Some("rs"), _) => Ordering::Less, - (_, Some("rs")) => Ordering::Greater, + (Some("rs" | "toml"), _) => Ordering::Less, + (_, Some("rs" | "toml")) => Ordering::Greater, _ => Ordering::Equal, } }); @@ -54,7 +54,7 @@ fn explore_directory(dir: &Path) -> Vec { let file_prefix = path.file_prefix().unwrap().to_str().unwrap().to_string(); if let Some(ext) = path.extension() { match ext.to_str().unwrap() { - "rs" => current_file = file_prefix.clone(), + "rs" | "toml" => current_file = file_prefix.clone(), "stderr" | "stdout" => { if file_prefix != current_file { missing_files.push(path.to_str().unwrap().to_string()); diff --git a/tests/ui-cargo/cargo_common_metadata/fail/src/main.stderr b/tests/ui-cargo/cargo_common_metadata/fail/Cargo.stderr similarity index 74% rename from tests/ui-cargo/cargo_common_metadata/fail/src/main.stderr rename to tests/ui-cargo/cargo_common_metadata/fail/Cargo.stderr index 86953142befa..e161507b5339 100644 --- a/tests/ui-cargo/cargo_common_metadata/fail/src/main.stderr +++ b/tests/ui-cargo/cargo_common_metadata/fail/Cargo.stderr @@ -1,6 +1,6 @@ error: package `cargo_common_metadata_fail` is missing `package.description` metadata - | - = note: `-D clippy::cargo-common-metadata` implied by `-D warnings` + | + = note: `-D clippy::cargo-common-metadata` implied by `-D warnings` error: package `cargo_common_metadata_fail` is missing `either package.license or package.license_file` metadata @@ -12,5 +12,4 @@ error: package `cargo_common_metadata_fail` is missing `package.keywords` metada error: package `cargo_common_metadata_fail` is missing `package.categories` metadata -error: aborting due to 6 previous errors - +error: could not compile `cargo_common_metadata_fail` (bin "cargo_common_metadata_fail") due to 6 previous errors diff --git a/tests/ui-cargo/cargo_common_metadata/fail/src/main.rs b/tests/ui-cargo/cargo_common_metadata/fail/src/main.rs index 27841e18aa9e..1a69bb24101e 100644 --- a/tests/ui-cargo/cargo_common_metadata/fail/src/main.rs +++ b/tests/ui-cargo/cargo_common_metadata/fail/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.stderr b/tests/ui-cargo/cargo_common_metadata/fail_publish/Cargo.stderr similarity index 74% rename from tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.stderr rename to tests/ui-cargo/cargo_common_metadata/fail_publish/Cargo.stderr index ac1b5e8e9034..dbf494cc342d 100644 --- a/tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.stderr +++ b/tests/ui-cargo/cargo_common_metadata/fail_publish/Cargo.stderr @@ -1,6 +1,6 @@ error: package `cargo_common_metadata_fail_publish` is missing `package.description` metadata - | - = note: `-D clippy::cargo-common-metadata` implied by `-D warnings` + | + = note: `-D clippy::cargo-common-metadata` implied by `-D warnings` error: package `cargo_common_metadata_fail_publish` is missing `either package.license or package.license_file` metadata @@ -12,5 +12,4 @@ error: package `cargo_common_metadata_fail_publish` is missing `package.keywords error: package `cargo_common_metadata_fail_publish` is missing `package.categories` metadata -error: aborting due to 6 previous errors - +error: could not compile `cargo_common_metadata_fail_publish` (bin "cargo_common_metadata_fail_publish") due to 6 previous errors diff --git a/tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.rs b/tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.rs index 27841e18aa9e..1a69bb24101e 100644 --- a/tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.rs +++ b/tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.stderr b/tests/ui-cargo/cargo_common_metadata/fail_publish_true/Cargo.stderr similarity index 74% rename from tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.stderr rename to tests/ui-cargo/cargo_common_metadata/fail_publish_true/Cargo.stderr index be32c0dc418f..ae5967406f62 100644 --- a/tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.stderr +++ b/tests/ui-cargo/cargo_common_metadata/fail_publish_true/Cargo.stderr @@ -1,6 +1,6 @@ error: package `cargo_common_metadata_fail_publish_true` is missing `package.description` metadata - | - = note: `-D clippy::cargo-common-metadata` implied by `-D warnings` + | + = note: `-D clippy::cargo-common-metadata` implied by `-D warnings` error: package `cargo_common_metadata_fail_publish_true` is missing `either package.license or package.license_file` metadata @@ -12,5 +12,4 @@ error: package `cargo_common_metadata_fail_publish_true` is missing `package.key error: package `cargo_common_metadata_fail_publish_true` is missing `package.categories` metadata -error: aborting due to 6 previous errors - +error: could not compile `cargo_common_metadata_fail_publish_true` (bin "cargo_common_metadata_fail_publish_true") due to 6 previous errors diff --git a/tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.rs b/tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.rs index 27841e18aa9e..1a69bb24101e 100644 --- a/tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.rs +++ b/tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/tests/ui-cargo/cargo_common_metadata/pass/src/main.rs b/tests/ui-cargo/cargo_common_metadata/pass/src/main.rs index 27841e18aa9e..1a69bb24101e 100644 --- a/tests/ui-cargo/cargo_common_metadata/pass/src/main.rs +++ b/tests/ui-cargo/cargo_common_metadata/pass/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/tests/ui-cargo/cargo_common_metadata/pass_publish_empty/src/main.rs b/tests/ui-cargo/cargo_common_metadata/pass_publish_empty/src/main.rs index 27841e18aa9e..1a69bb24101e 100644 --- a/tests/ui-cargo/cargo_common_metadata/pass_publish_empty/src/main.rs +++ b/tests/ui-cargo/cargo_common_metadata/pass_publish_empty/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/tests/ui-cargo/cargo_common_metadata/pass_publish_false/src/main.rs b/tests/ui-cargo/cargo_common_metadata/pass_publish_false/src/main.rs index 27841e18aa9e..1a69bb24101e 100644 --- a/tests/ui-cargo/cargo_common_metadata/pass_publish_false/src/main.rs +++ b/tests/ui-cargo/cargo_common_metadata/pass_publish_false/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/tests/ui-cargo/cargo_rust_version/fail_both_diff/Cargo.stderr b/tests/ui-cargo/cargo_rust_version/fail_both_diff/Cargo.stderr new file mode 100644 index 000000000000..dfbf19d33a5e --- /dev/null +++ b/tests/ui-cargo/cargo_rust_version/fail_both_diff/Cargo.stderr @@ -0,0 +1,21 @@ +warning: the MSRV in `clippy.toml` and `Cargo.toml` differ; using `1.59.0` from `clippy.toml` + +error: unnecessary structure name repetition + --> src/main.rs:6:21 + | +6 | pub fn bar() -> Foo { + | ^^^ help: use the applicable keyword: `Self` + | +note: the lint level is defined here + --> src/main.rs:1:9 + | +1 | #![deny(clippy::use_self)] + | ^^^^^^^^^^^^^^^^ + +error: unnecessary structure name repetition + --> src/main.rs:7:9 + | +7 | Foo + | ^^^ help: use the applicable keyword: `Self` + +error: could not compile `fail-both-diff` (bin "fail-both-diff") due to 2 previous errors; 1 warning emitted diff --git a/tests/ui-cargo/cargo_rust_version/fail_both_diff/src/main.stderr b/tests/ui-cargo/cargo_rust_version/fail_both_diff/src/main.stderr deleted file mode 100644 index 163f8bb35e79..000000000000 --- a/tests/ui-cargo/cargo_rust_version/fail_both_diff/src/main.stderr +++ /dev/null @@ -1,22 +0,0 @@ -warning: the MSRV in `clippy.toml` and `Cargo.toml` differ; using `1.59.0` from `clippy.toml` - -error: unnecessary structure name repetition - --> $DIR/main.rs:6:21 - | -LL | pub fn bar() -> Foo { - | ^^^ help: use the applicable keyword: `Self` - | -note: the lint level is defined here - --> $DIR/main.rs:1:9 - | -LL | #![deny(clippy::use_self)] - | ^^^^^^^^^^^^^^^^ - -error: unnecessary structure name repetition - --> $DIR/main.rs:7:9 - | -LL | Foo - | ^^^ help: use the applicable keyword: `Self` - -error: aborting due to 2 previous errors; 1 warning emitted - diff --git a/tests/ui-cargo/cargo_rust_version/fail_both_same/Cargo.stderr b/tests/ui-cargo/cargo_rust_version/fail_both_same/Cargo.stderr new file mode 100644 index 000000000000..407a9055de80 --- /dev/null +++ b/tests/ui-cargo/cargo_rust_version/fail_both_same/Cargo.stderr @@ -0,0 +1,19 @@ +error: unnecessary structure name repetition + --> src/main.rs:6:21 + | +6 | pub fn bar() -> Foo { + | ^^^ help: use the applicable keyword: `Self` + | +note: the lint level is defined here + --> src/main.rs:1:9 + | +1 | #![deny(clippy::use_self)] + | ^^^^^^^^^^^^^^^^ + +error: unnecessary structure name repetition + --> src/main.rs:7:9 + | +7 | Foo + | ^^^ help: use the applicable keyword: `Self` + +error: could not compile `fail-both-same` (bin "fail-both-same") due to 2 previous errors diff --git a/tests/ui-cargo/cargo_rust_version/fail_both_same/src/main.stderr b/tests/ui-cargo/cargo_rust_version/fail_both_same/src/main.stderr deleted file mode 100644 index 259d39b12526..000000000000 --- a/tests/ui-cargo/cargo_rust_version/fail_both_same/src/main.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: unnecessary structure name repetition - --> $DIR/main.rs:6:21 - | -LL | pub fn bar() -> Foo { - | ^^^ help: use the applicable keyword: `Self` - | -note: the lint level is defined here - --> $DIR/main.rs:1:9 - | -LL | #![deny(clippy::use_self)] - | ^^^^^^^^^^^^^^^^ - -error: unnecessary structure name repetition - --> $DIR/main.rs:7:9 - | -LL | Foo - | ^^^ help: use the applicable keyword: `Self` - -error: aborting due to 2 previous errors - diff --git a/tests/ui-cargo/cargo_rust_version/fail_cargo/Cargo.stderr b/tests/ui-cargo/cargo_rust_version/fail_cargo/Cargo.stderr new file mode 100644 index 000000000000..566f5a68689b --- /dev/null +++ b/tests/ui-cargo/cargo_rust_version/fail_cargo/Cargo.stderr @@ -0,0 +1,19 @@ +error: unnecessary structure name repetition + --> src/main.rs:6:21 + | +6 | pub fn bar() -> Foo { + | ^^^ help: use the applicable keyword: `Self` + | +note: the lint level is defined here + --> src/main.rs:1:9 + | +1 | #![deny(clippy::use_self)] + | ^^^^^^^^^^^^^^^^ + +error: unnecessary structure name repetition + --> src/main.rs:7:9 + | +7 | Foo + | ^^^ help: use the applicable keyword: `Self` + +error: could not compile `fail-cargo` (bin "fail-cargo") due to 2 previous errors diff --git a/tests/ui-cargo/cargo_rust_version/fail_cargo/src/main.stderr b/tests/ui-cargo/cargo_rust_version/fail_cargo/src/main.stderr deleted file mode 100644 index 259d39b12526..000000000000 --- a/tests/ui-cargo/cargo_rust_version/fail_cargo/src/main.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: unnecessary structure name repetition - --> $DIR/main.rs:6:21 - | -LL | pub fn bar() -> Foo { - | ^^^ help: use the applicable keyword: `Self` - | -note: the lint level is defined here - --> $DIR/main.rs:1:9 - | -LL | #![deny(clippy::use_self)] - | ^^^^^^^^^^^^^^^^ - -error: unnecessary structure name repetition - --> $DIR/main.rs:7:9 - | -LL | Foo - | ^^^ help: use the applicable keyword: `Self` - -error: aborting due to 2 previous errors - diff --git a/tests/ui-cargo/cargo_rust_version/fail_clippy/Cargo.stderr b/tests/ui-cargo/cargo_rust_version/fail_clippy/Cargo.stderr new file mode 100644 index 000000000000..83d4be3bae46 --- /dev/null +++ b/tests/ui-cargo/cargo_rust_version/fail_clippy/Cargo.stderr @@ -0,0 +1,19 @@ +error: unnecessary structure name repetition + --> src/main.rs:6:21 + | +6 | pub fn bar() -> Foo { + | ^^^ help: use the applicable keyword: `Self` + | +note: the lint level is defined here + --> src/main.rs:1:9 + | +1 | #![deny(clippy::use_self)] + | ^^^^^^^^^^^^^^^^ + +error: unnecessary structure name repetition + --> src/main.rs:7:9 + | +7 | Foo + | ^^^ help: use the applicable keyword: `Self` + +error: could not compile `fail-clippy` (bin "fail-clippy") due to 2 previous errors diff --git a/tests/ui-cargo/cargo_rust_version/fail_clippy/src/main.stderr b/tests/ui-cargo/cargo_rust_version/fail_file_attr/Cargo.stderr similarity index 56% rename from tests/ui-cargo/cargo_rust_version/fail_clippy/src/main.stderr rename to tests/ui-cargo/cargo_rust_version/fail_file_attr/Cargo.stderr index 259d39b12526..14a6b5047b18 100644 --- a/tests/ui-cargo/cargo_rust_version/fail_clippy/src/main.stderr +++ b/tests/ui-cargo/cargo_rust_version/fail_file_attr/Cargo.stderr @@ -1,20 +1,19 @@ error: unnecessary structure name repetition - --> $DIR/main.rs:6:21 + --> src/main.rs:11:21 | -LL | pub fn bar() -> Foo { +11 | pub fn bar() -> Foo { | ^^^ help: use the applicable keyword: `Self` | note: the lint level is defined here - --> $DIR/main.rs:1:9 + --> src/main.rs:6:9 | -LL | #![deny(clippy::use_self)] +6 | #![deny(clippy::use_self)] | ^^^^^^^^^^^^^^^^ error: unnecessary structure name repetition - --> $DIR/main.rs:7:9 + --> src/main.rs:12:9 | -LL | Foo +12 | Foo | ^^^ help: use the applicable keyword: `Self` -error: aborting due to 2 previous errors - +error: could not compile `fail-file-attr` (bin "fail-file-attr") due to 2 previous errors diff --git a/tests/ui-cargo/cargo_rust_version/fail_file_attr/src/main.stderr b/tests/ui-cargo/cargo_rust_version/fail_file_attr/src/main.stderr deleted file mode 100644 index 97e6c3d5a559..000000000000 --- a/tests/ui-cargo/cargo_rust_version/fail_file_attr/src/main.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: unnecessary structure name repetition - --> $DIR/main.rs:11:21 - | -LL | pub fn bar() -> Foo { - | ^^^ help: use the applicable keyword: `Self` - | -note: the lint level is defined here - --> $DIR/main.rs:6:9 - | -LL | #![deny(clippy::use_self)] - | ^^^^^^^^^^^^^^^^ - -error: unnecessary structure name repetition - --> $DIR/main.rs:12:9 - | -LL | Foo - | ^^^ help: use the applicable keyword: `Self` - -error: aborting due to 2 previous errors - diff --git a/tests/ui-cargo/cargo_rust_version/warn_both_diff/src/main.stderr b/tests/ui-cargo/cargo_rust_version/warn_both_diff/Cargo.stderr similarity index 77% rename from tests/ui-cargo/cargo_rust_version/warn_both_diff/src/main.stderr rename to tests/ui-cargo/cargo_rust_version/warn_both_diff/Cargo.stderr index eeae5b7b275e..e89388b501bf 100644 --- a/tests/ui-cargo/cargo_rust_version/warn_both_diff/src/main.stderr +++ b/tests/ui-cargo/cargo_rust_version/warn_both_diff/Cargo.stderr @@ -1,4 +1,2 @@ warning: the MSRV in `clippy.toml` and `Cargo.toml` differ; using `1.13.0` from `clippy.toml` -warning: 1 warning emitted - diff --git a/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr b/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr new file mode 100644 index 000000000000..fde3a1e65991 --- /dev/null +++ b/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr @@ -0,0 +1,52 @@ +error: file is loaded as a module multiple times: `src/b.rs` + --> src/main.rs:5:1 + | +5 | mod b; + | ^^^^^^ first loaded here +6 | / #[path = "b.rs"] +7 | | mod b2; + | |_______^ loaded again here + | + = help: replace all but one `mod` item with `use` items + = note: `-D clippy::duplicate-mod` implied by `-D warnings` + +error: file is loaded as a module multiple times: `src/c.rs` + --> src/main.rs:9:1 + | +9 | mod c; + | ^^^^^^ first loaded here +10 | / #[path = "c.rs"] +11 | | mod c2; + | |_______^ loaded again here +12 | / #[path = "c.rs"] +13 | | mod c3; + | |_______^ loaded again here + | + = help: replace all but one `mod` item with `use` items + +error: file is loaded as a module multiple times: `src/d.rs` + --> src/main.rs:18:1 + | +18 | mod d; + | ^^^^^^ first loaded here +19 | / #[path = "d.rs"] +20 | | mod d2; + | |_______^ loaded again here + | + = help: replace all but one `mod` item with `use` items + +error: file is loaded as a module multiple times: `src/from_other_module.rs` + --> src/main.rs:15:1 + | +15 | mod from_other_module; + | ^^^^^^^^^^^^^^^^^^^^^^ first loaded here + | + ::: src/other_module/mod.rs:1:1 + | +1 | / #[path = "../from_other_module.rs"] +2 | | mod m; + | |______^ loaded again here + | + = help: replace all but one `mod` item with `use` items + +error: could not compile `duplicate_mod` (bin "duplicate_mod") due to 4 previous errors diff --git a/tests/ui-cargo/duplicate_mod/fail/src/main.stderr b/tests/ui-cargo/duplicate_mod/fail/src/main.stderr deleted file mode 100644 index 3b80d89a6865..000000000000 --- a/tests/ui-cargo/duplicate_mod/fail/src/main.stderr +++ /dev/null @@ -1,53 +0,0 @@ -error: file is loaded as a module multiple times: `$DIR/b.rs` - --> $DIR/main.rs:5:1 - | -LL | mod b; - | ^^^^^^ first loaded here -LL | / #[path = "b.rs"] -LL | | mod b2; - | |_______^ loaded again here - | - = help: replace all but one `mod` item with `use` items - = note: `-D clippy::duplicate-mod` implied by `-D warnings` - -error: file is loaded as a module multiple times: `$DIR/c.rs` - --> $DIR/main.rs:9:1 - | -LL | mod c; - | ^^^^^^ first loaded here -LL | / #[path = "c.rs"] -LL | | mod c2; - | |_______^ loaded again here -LL | / #[path = "c.rs"] -LL | | mod c3; - | |_______^ loaded again here - | - = help: replace all but one `mod` item with `use` items - -error: file is loaded as a module multiple times: `$DIR/d.rs` - --> $DIR/main.rs:18:1 - | -LL | mod d; - | ^^^^^^ first loaded here -LL | / #[path = "d.rs"] -LL | | mod d2; - | |_______^ loaded again here - | - = help: replace all but one `mod` item with `use` items - -error: file is loaded as a module multiple times: `$DIR/from_other_module.rs` - --> $DIR/main.rs:15:1 - | -LL | mod from_other_module; - | ^^^^^^^^^^^^^^^^^^^^^^ first loaded here - | - ::: $DIR/other_module/mod.rs:1:1 - | -LL | / #[path = "../from_other_module.rs"] -LL | | mod m; - | |______^ loaded again here - | - = help: replace all but one `mod` item with `use` items - -error: aborting due to 4 previous errors - diff --git a/tests/ui-cargo/feature_name/fail/Cargo.stderr b/tests/ui-cargo/feature_name/fail/Cargo.stderr new file mode 100644 index 000000000000..da2db45d3b83 --- /dev/null +++ b/tests/ui-cargo/feature_name/fail/Cargo.stderr @@ -0,0 +1,43 @@ +error: the "no-" prefix in the feature name "no-qaq" is negative + | + = help: consider renaming the feature to "qaq", but make sure the feature adds functionality + = note: `-D clippy::negative-feature-names` implied by `-D warnings` + +error: the "no_" prefix in the feature name "no_qaq" is negative + | + = help: consider renaming the feature to "qaq", but make sure the feature adds functionality + +error: the "not-" prefix in the feature name "not-orz" is negative + | + = help: consider renaming the feature to "orz", but make sure the feature adds functionality + +error: the "not_" prefix in the feature name "not_orz" is negative + | + = help: consider renaming the feature to "orz", but make sure the feature adds functionality + +error: the "-support" suffix in the feature name "qvq-support" is redundant + | + = help: consider renaming the feature to "qvq" + = note: `-D clippy::redundant-feature-names` implied by `-D warnings` + +error: the "_support" suffix in the feature name "qvq_support" is redundant + | + = help: consider renaming the feature to "qvq" + +error: the "use-" prefix in the feature name "use-qwq" is redundant + | + = help: consider renaming the feature to "qwq" + +error: the "use_" prefix in the feature name "use_qwq" is redundant + | + = help: consider renaming the feature to "qwq" + +error: the "with-" prefix in the feature name "with-owo" is redundant + | + = help: consider renaming the feature to "owo" + +error: the "with_" prefix in the feature name "with_owo" is redundant + | + = help: consider renaming the feature to "owo" + +error: could not compile `feature_name` (bin "feature_name") due to 10 previous errors diff --git a/tests/ui-cargo/feature_name/fail/src/main.rs b/tests/ui-cargo/feature_name/fail/src/main.rs index 64f01a98c90e..4dd9582aff89 100644 --- a/tests/ui-cargo/feature_name/fail/src/main.rs +++ b/tests/ui-cargo/feature_name/fail/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=feature_name +//@compile-flags: --crate-name=feature_name #![warn(clippy::redundant_feature_names)] #![warn(clippy::negative_feature_names)] diff --git a/tests/ui-cargo/feature_name/fail/src/main.stderr b/tests/ui-cargo/feature_name/fail/src/main.stderr deleted file mode 100644 index c6a11fa93eb5..000000000000 --- a/tests/ui-cargo/feature_name/fail/src/main.stderr +++ /dev/null @@ -1,44 +0,0 @@ -error: the "no-" prefix in the feature name "no-qaq" is negative - | - = help: consider renaming the feature to "qaq", but make sure the feature adds functionality - = note: `-D clippy::negative-feature-names` implied by `-D warnings` - -error: the "no_" prefix in the feature name "no_qaq" is negative - | - = help: consider renaming the feature to "qaq", but make sure the feature adds functionality - -error: the "not-" prefix in the feature name "not-orz" is negative - | - = help: consider renaming the feature to "orz", but make sure the feature adds functionality - -error: the "not_" prefix in the feature name "not_orz" is negative - | - = help: consider renaming the feature to "orz", but make sure the feature adds functionality - -error: the "-support" suffix in the feature name "qvq-support" is redundant - | - = help: consider renaming the feature to "qvq" - = note: `-D clippy::redundant-feature-names` implied by `-D warnings` - -error: the "_support" suffix in the feature name "qvq_support" is redundant - | - = help: consider renaming the feature to "qvq" - -error: the "use-" prefix in the feature name "use-qwq" is redundant - | - = help: consider renaming the feature to "qwq" - -error: the "use_" prefix in the feature name "use_qwq" is redundant - | - = help: consider renaming the feature to "qwq" - -error: the "with-" prefix in the feature name "with-owo" is redundant - | - = help: consider renaming the feature to "owo" - -error: the "with_" prefix in the feature name "with_owo" is redundant - | - = help: consider renaming the feature to "owo" - -error: aborting due to 10 previous errors - diff --git a/tests/ui-cargo/feature_name/pass/src/main.rs b/tests/ui-cargo/feature_name/pass/src/main.rs index 64f01a98c90e..4dd9582aff89 100644 --- a/tests/ui-cargo/feature_name/pass/src/main.rs +++ b/tests/ui-cargo/feature_name/pass/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=feature_name +//@compile-flags: --crate-name=feature_name #![warn(clippy::redundant_feature_names)] #![warn(clippy::negative_feature_names)] diff --git a/tests/ui-cargo/module_style/fail_mod/Cargo.stderr b/tests/ui-cargo/module_style/fail_mod/Cargo.stderr new file mode 100644 index 000000000000..c2907f319e64 --- /dev/null +++ b/tests/ui-cargo/module_style/fail_mod/Cargo.stderr @@ -0,0 +1,18 @@ +error: `mod.rs` files are required, found `src/bad/inner.rs` + --> src/bad/inner.rs:1:1 + | +1 | pub mod stuff; + | ^ + | + = help: move `src/bad/inner.rs` to `src/bad/inner/mod.rs` + = note: `-D clippy::self-named-module-files` implied by `-D warnings` + +error: `mod.rs` files are required, found `src/bad/inner/stuff.rs` + --> src/bad/inner/stuff.rs:1:1 + | +1 | pub mod most; + | ^ + | + = help: move `src/bad/inner/stuff.rs` to `src/bad/inner/stuff/mod.rs` + +error: could not compile `fail-mod` (bin "fail-mod") due to 2 previous errors diff --git a/tests/ui-cargo/module_style/fail_mod/src/main.stderr b/tests/ui-cargo/module_style/fail_mod/src/main.stderr deleted file mode 100644 index 697c8b57c4a2..000000000000 --- a/tests/ui-cargo/module_style/fail_mod/src/main.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: `mod.rs` files are required, found `bad/inner.rs` - --> $DIR/bad/inner.rs:1:1 - | -LL | pub mod stuff; - | ^ - | - = help: move `bad/inner.rs` to `bad/inner/mod.rs` - = note: `-D clippy::self-named-module-files` implied by `-D warnings` - -error: `mod.rs` files are required, found `bad/inner/stuff.rs` - --> $DIR/bad/inner/stuff.rs:1:1 - | -LL | pub mod most; - | ^ - | - = help: move `bad/inner/stuff.rs` to `bad/inner/stuff/mod.rs` - -error: aborting due to 2 previous errors - diff --git a/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr b/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr new file mode 100644 index 000000000000..fcf1a3c5e66c --- /dev/null +++ b/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr @@ -0,0 +1,10 @@ +error: `mod.rs` files are required, found `src/bad.rs` + --> src/bad.rs:1:1 + | +1 | pub mod inner; + | ^ + | + = help: move `src/bad.rs` to `src/bad/mod.rs` + = note: `-D clippy::self-named-module-files` implied by `-D warnings` + +error: could not compile `fail-mod-remap` (bin "fail-mod-remap") due to previous error diff --git a/tests/ui-cargo/module_style/fail_mod_remap/src/main.rs b/tests/ui-cargo/module_style/fail_mod_remap/src/main.rs index ba4c8c873dd5..c70d92e359e4 100644 --- a/tests/ui-cargo/module_style/fail_mod_remap/src/main.rs +++ b/tests/ui-cargo/module_style/fail_mod_remap/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --remap-path-prefix {{src-base}}=/remapped +//@compile-flags: --remap-path-prefix {{src-base}}=/remapped #![warn(clippy::self_named_module_files)] diff --git a/tests/ui-cargo/module_style/fail_mod_remap/src/main.stderr b/tests/ui-cargo/module_style/fail_mod_remap/src/main.stderr deleted file mode 100644 index ea6ea98064a7..000000000000 --- a/tests/ui-cargo/module_style/fail_mod_remap/src/main.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: `mod.rs` files are required, found `bad.rs` - --> /remapped/module_style/fail_mod_remap/src/bad.rs:1:1 - | -LL | pub mod inner; - | ^ - | - = help: move `bad.rs` to `bad/mod.rs` - = note: `-D clippy::self-named-module-files` implied by `-D warnings` - -error: aborting due to previous error - diff --git a/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr b/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr new file mode 100644 index 000000000000..f61642ca2efd --- /dev/null +++ b/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr @@ -0,0 +1,10 @@ +error: `mod.rs` files are not allowed, found `src/bad/mod.rs` + --> src/bad/mod.rs:1:1 + | +1 | pub struct Thing; + | ^ + | + = help: move `src/bad/mod.rs` to `src/bad.rs` + = note: `-D clippy::mod-module-files` implied by `-D warnings` + +error: could not compile `fail-no-mod` (bin "fail-no-mod") due to previous error diff --git a/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr b/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr deleted file mode 100644 index f40ceea234b9..000000000000 --- a/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: `mod.rs` files are not allowed, found `bad/mod.rs` - --> $DIR/bad/mod.rs:1:1 - | -LL | pub struct Thing; - | ^ - | - = help: move `bad/mod.rs` to `bad.rs` - = note: `-D clippy::mod-module-files` implied by `-D warnings` - -error: aborting due to previous error - diff --git a/tests/ui-cargo/multiple_config_files/warn/Cargo.stderr b/tests/ui-cargo/multiple_config_files/warn/Cargo.stderr new file mode 100644 index 000000000000..d82b9e73f786 --- /dev/null +++ b/tests/ui-cargo/multiple_config_files/warn/Cargo.stderr @@ -0,0 +1,2 @@ +warning: using config file `$DIR/$DIR/.clippy.toml`, `$DIR/$DIR/clippy.toml` will be ignored + diff --git a/tests/ui-cargo/multiple_config_files/warn/src/main.stderr b/tests/ui-cargo/multiple_config_files/warn/src/main.stderr deleted file mode 100644 index aa1b3c638a03..000000000000 --- a/tests/ui-cargo/multiple_config_files/warn/src/main.stderr +++ /dev/null @@ -1,4 +0,0 @@ -warning: using config file `$SRC_DIR/.clippy.toml`, `$SRC_DIR/clippy.toml` will be ignored - -warning: 1 warning emitted - diff --git a/tests/ui-cargo/multiple_crate_versions/5041_allow_dev_build/src/main.rs b/tests/ui-cargo/multiple_crate_versions/5041_allow_dev_build/src/main.rs index 1b2d3ec9459f..ece260b743df 100644 --- a/tests/ui-cargo/multiple_crate_versions/5041_allow_dev_build/src/main.rs +++ b/tests/ui-cargo/multiple_crate_versions/5041_allow_dev_build/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=multiple_crate_versions +//@compile-flags: --crate-name=multiple_crate_versions #![warn(clippy::multiple_crate_versions)] fn main() {} diff --git a/tests/ui-cargo/multiple_crate_versions/fail/Cargo.lock b/tests/ui-cargo/multiple_crate_versions/fail/Cargo.lock index 7e96aa36feb4..e4de82ad3b83 100644 --- a/tests/ui-cargo/multiple_crate_versions/fail/Cargo.lock +++ b/tests/ui-cargo/multiple_crate_versions/fail/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "ansi_term" version = "0.11.0" @@ -9,71 +11,14 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "bitflags" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "ctrlc" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653abc99aa905f693d89df4797fadc08085baee379db92be9f2496cefe8a6f2c" -dependencies = [ - "kernel32-sys", - "nix", - "winapi 0.2.8", -] - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "libc" -version = "0.2.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" - [[package]] name = "multiple_crate_versions" version = "0.1.0" dependencies = [ "ansi_term", - "ctrlc", -] - -[[package]] -name = "nix" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2c5afeb0198ec7be8569d666644b574345aad2e95a53baf3a532da3e0f3fb32" -dependencies = [ - "bitflags", - "cfg-if", - "libc", - "void", + "winapi 0.2.8", ] -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - [[package]] name = "winapi" version = "0.2.8" @@ -90,12 +35,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" diff --git a/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr b/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr new file mode 100644 index 000000000000..5bcce920455c --- /dev/null +++ b/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr @@ -0,0 +1,5 @@ +error: multiple versions for dependency `winapi`: 0.2.8, 0.3.9 + | + = note: `-D clippy::multiple-crate-versions` implied by `-D warnings` + +error: could not compile `multiple_crate_versions` (bin "multiple_crate_versions") due to previous error diff --git a/tests/ui-cargo/multiple_crate_versions/fail/Cargo.toml b/tests/ui-cargo/multiple_crate_versions/fail/Cargo.toml index 4f97b0113340..79317659ac07 100644 --- a/tests/ui-cargo/multiple_crate_versions/fail/Cargo.toml +++ b/tests/ui-cargo/multiple_crate_versions/fail/Cargo.toml @@ -6,5 +6,5 @@ publish = false [workspace] [dependencies] -ctrlc = "=3.1.0" +winapi = "0.2" ansi_term = "=0.11.0" diff --git a/tests/ui-cargo/multiple_crate_versions/fail/src/main.rs b/tests/ui-cargo/multiple_crate_versions/fail/src/main.rs index 1b2d3ec9459f..ece260b743df 100644 --- a/tests/ui-cargo/multiple_crate_versions/fail/src/main.rs +++ b/tests/ui-cargo/multiple_crate_versions/fail/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=multiple_crate_versions +//@compile-flags: --crate-name=multiple_crate_versions #![warn(clippy::multiple_crate_versions)] fn main() {} diff --git a/tests/ui-cargo/multiple_crate_versions/fail/src/main.stderr b/tests/ui-cargo/multiple_crate_versions/fail/src/main.stderr deleted file mode 100644 index f3113e093650..000000000000 --- a/tests/ui-cargo/multiple_crate_versions/fail/src/main.stderr +++ /dev/null @@ -1,6 +0,0 @@ -error: multiple versions for dependency `winapi`: 0.2.8, 0.3.9 - | - = note: `-D clippy::multiple-crate-versions` implied by `-D warnings` - -error: aborting due to previous error - diff --git a/tests/ui-cargo/multiple_crate_versions/pass/src/main.rs b/tests/ui-cargo/multiple_crate_versions/pass/src/main.rs index 1b2d3ec9459f..ece260b743df 100644 --- a/tests/ui-cargo/multiple_crate_versions/pass/src/main.rs +++ b/tests/ui-cargo/multiple_crate_versions/pass/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=multiple_crate_versions +//@compile-flags: --crate-name=multiple_crate_versions #![warn(clippy::multiple_crate_versions)] fn main() {} diff --git a/tests/ui-cargo/update-all-references.sh b/tests/ui-cargo/update-all-references.sh index 4391499a1e1f..d42043070261 100755 --- a/tests/ui-cargo/update-all-references.sh +++ b/tests/ui-cargo/update-all-references.sh @@ -1,3 +1,3 @@ #!/bin/bash -echo "Please use 'cargo dev bless' instead." +echo "Please use 'cargo bless' instead." diff --git a/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr b/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr new file mode 100644 index 000000000000..b1578c9f3249 --- /dev/null +++ b/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr @@ -0,0 +1,5 @@ +error: wildcard dependency for `regex` + | + = note: `-D clippy::wildcard-dependencies` implied by `-D warnings` + +error: could not compile `wildcard_dependencies` (bin "wildcard_dependencies") due to previous error diff --git a/tests/ui-cargo/wildcard_dependencies/fail/src/main.rs b/tests/ui-cargo/wildcard_dependencies/fail/src/main.rs index 581babfeacbf..bb3a39d0720a 100644 --- a/tests/ui-cargo/wildcard_dependencies/fail/src/main.rs +++ b/tests/ui-cargo/wildcard_dependencies/fail/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=wildcard_dependencies +//@compile-flags: --crate-name=wildcard_dependencies #![warn(clippy::wildcard_dependencies)] fn main() {} diff --git a/tests/ui-cargo/wildcard_dependencies/fail/src/main.stderr b/tests/ui-cargo/wildcard_dependencies/fail/src/main.stderr deleted file mode 100644 index 9e65d2f99420..000000000000 --- a/tests/ui-cargo/wildcard_dependencies/fail/src/main.stderr +++ /dev/null @@ -1,6 +0,0 @@ -error: wildcard dependency for `regex` - | - = note: `-D clippy::wildcard-dependencies` implied by `-D warnings` - -error: aborting due to previous error - diff --git a/tests/ui-cargo/wildcard_dependencies/pass/src/main.rs b/tests/ui-cargo/wildcard_dependencies/pass/src/main.rs index 581babfeacbf..bb3a39d0720a 100644 --- a/tests/ui-cargo/wildcard_dependencies/pass/src/main.rs +++ b/tests/ui-cargo/wildcard_dependencies/pass/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=wildcard_dependencies +//@compile-flags: --crate-name=wildcard_dependencies #![warn(clippy::wildcard_dependencies)] fn main() {} diff --git a/tests/ui-internal/check_formulation.rs b/tests/ui-internal/check_formulation.rs new file mode 100644 index 000000000000..af63d6df73e4 --- /dev/null +++ b/tests/ui-internal/check_formulation.rs @@ -0,0 +1,63 @@ +#![warn(clippy::almost_standard_lint_formulation)] +#![feature(rustc_private)] + +#[macro_use] +extern crate rustc_middle; +#[macro_use] +extern crate rustc_session; +extern crate rustc_lint; + +declare_tool_lint! { + /// # What it does + /// + /// Checks for usage of correct lint formulations + #[clippy::version = "pre 1.29.0"] + pub clippy::VALID, + Warn, + "One", + report_in_external_macro: true +} + +declare_tool_lint! { + /// # What it does + /// Check for lint formulations that are correct + #[clippy::version = "pre 1.29.0"] + pub clippy::INVALID1, + Warn, + "One", + report_in_external_macro: true +} + +declare_tool_lint! { + /// # What it does + /// Detects uses of incorrect formulations + #[clippy::version = "pre 1.29.0"] + pub clippy::INVALID2, + Warn, + "One", + report_in_external_macro: true +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 50c93bbfd (refactor(test): Move attribute to lint level) +declare_tool_lint! { + /// # What it does + /// Detects uses of incorrect formulations (allowed with attribute) + #[allow(clippy::almost_standard_lint_formulation)] + #[clippy::version = "pre 1.29.0"] + pub clippy::ALLOWED_INVALID, + Warn, + "One", + report_in_external_macro: true +} + +<<<<<<< HEAD +======= +>>>>>>> 7ac15f900 (Add lint to check lint formulation messages) +======= +>>>>>>> 50c93bbfd (refactor(test): Move attribute to lint level) +declare_lint_pass!(Pass => [VALID, INVALID1, INVALID2]); + +fn main() {} diff --git a/tests/ui-internal/check_formulation.stderr b/tests/ui-internal/check_formulation.stderr new file mode 100644 index 000000000000..10eabca4b9d7 --- /dev/null +++ b/tests/ui-internal/check_formulation.stderr @@ -0,0 +1,19 @@ +error: non-standard lint formulation + --> $DIR/check_formulation.rs:23:5 + | +LL | /// Check for lint formulations that are correct + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try using `Checks for` instead + = note: `-D clippy::almost-standard-lint-formulation` implied by `-D warnings` + +error: non-standard lint formulation + --> $DIR/check_formulation.rs:33:5 + | +LL | /// Detects uses of incorrect formulations + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try using `Checks for` instead + +error: aborting due to 2 previous errors + diff --git a/tests/ui-internal/collapsible_span_lint_calls.fixed b/tests/ui-internal/collapsible_span_lint_calls.fixed index 9f299d7dec72..72c04bf80b6b 100644 --- a/tests/ui-internal/collapsible_span_lint_calls.fixed +++ b/tests/ui-internal/collapsible_span_lint_calls.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] #![feature(rustc_private)] diff --git a/tests/ui-internal/collapsible_span_lint_calls.rs b/tests/ui-internal/collapsible_span_lint_calls.rs index 2b113f555e46..76f7c3ce94d6 100644 --- a/tests/ui-internal/collapsible_span_lint_calls.rs +++ b/tests/ui-internal/collapsible_span_lint_calls.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] #![feature(rustc_private)] diff --git a/tests/ui-internal/custom_ice_message.rs b/tests/ui-internal/custom_ice_message.rs index 837811bdf1ef..f9dde56bb0f9 100644 --- a/tests/ui-internal/custom_ice_message.rs +++ b/tests/ui-internal/custom_ice_message.rs @@ -1,9 +1,13 @@ -// rustc-env:RUST_BACKTRACE=0 -// normalize-stderr-test: "Clippy version: .*" -> "Clippy version: foo" -// normalize-stderr-test: "produce_ice.rs:\d*:\d*" -> "produce_ice.rs" -// normalize-stderr-test: "', .*clippy_lints" -> "', clippy_lints" -// normalize-stderr-test: "'rustc'" -> "''" -// normalize-stderr-test: "(?ms)query stack during panic:\n.*end of query stack\n" -> "" +//@rustc-env:RUST_BACKTRACE=0 +//@normalize-stderr-test: "Clippy version: .*" -> "Clippy version: foo" +//@normalize-stderr-test: "produce_ice.rs:\d*:\d*" -> "produce_ice.rs" +//@normalize-stderr-test: "', .*clippy_lints" -> "', clippy_lints" +//@normalize-stderr-test: "'rustc'" -> "''" +<<<<<<< HEAD +//@normalize-stderr-test: "rustc 1\.\d+.* running on .*" -> "rustc running on " +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +//@normalize-stderr-test: "(?ms)query stack during panic:\n.*end of query stack\n" -> "" #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/tests/ui-internal/custom_ice_message.stderr b/tests/ui-internal/custom_ice_message.stderr index b4619e980f30..3c49fb15374f 100644 --- a/tests/ui-internal/custom_ice_message.stderr +++ b/tests/ui-internal/custom_ice_message.stderr @@ -1,12 +1,16 @@ thread '' panicked at 'Would you like some help with that?', clippy_lints/src/utils/internal_lints/produce_ice.rs note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -error: internal compiler error: unexpected panic - -note: the compiler unexpectedly panicked. this is a bug. +error: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new +note: rustc running on + +note: compiler flags: -Z ui-testing +<<<<<<< HEAD + note: Clippy version: foo +======= +>>>>>>> 5bd97ac17 (Update tests) -thread panicked while panicking. aborting. diff --git a/tests/ui-internal/if_chain_style.rs b/tests/ui-internal/if_chain_style.rs index b0d89e038aa8..b462b20e04c6 100644 --- a/tests/ui-internal/if_chain_style.rs +++ b/tests/ui-internal/if_chain_style.rs @@ -1,5 +1,10 @@ #![warn(clippy::if_chain_style)] -#![allow(clippy::no_effect, clippy::nonminimal_bool, clippy::missing_clippy_version_attribute)] +#![allow( + clippy::needless_if, + clippy::no_effect, + clippy::nonminimal_bool, + clippy::missing_clippy_version_attribute +)] extern crate if_chain; diff --git a/tests/ui-internal/if_chain_style.stderr b/tests/ui-internal/if_chain_style.stderr index d8f1ffb21ba6..b12df2786520 100644 --- a/tests/ui-internal/if_chain_style.stderr +++ b/tests/ui-internal/if_chain_style.stderr @@ -1,5 +1,5 @@ error: this `if` can be part of the inner `if_chain!` - --> $DIR/if_chain_style.rs:9:5 + --> $DIR/if_chain_style.rs:14:5 | LL | / if true { LL | | let x = ""; @@ -11,14 +11,14 @@ LL | | } | |_____^ | help: this `let` statement can also be in the `if_chain!` - --> $DIR/if_chain_style.rs:10:9 + --> $DIR/if_chain_style.rs:15:9 | LL | let x = ""; | ^^^^^^^^^^^ = note: `-D clippy::if-chain-style` implied by `-D warnings` error: `if a && b;` should be `if a; if b;` - --> $DIR/if_chain_style.rs:19:12 + --> $DIR/if_chain_style.rs:24:12 | LL | if true | ____________^ @@ -27,25 +27,25 @@ LL | | && false; | |____________________^ error: `let` expression should be inside `then { .. }` - --> $DIR/if_chain_style.rs:24:9 + --> $DIR/if_chain_style.rs:29:9 | LL | let x = ""; | ^^^^^^^^^^^ error: this `if` can be part of the outer `if_chain!` - --> $DIR/if_chain_style.rs:35:13 + --> $DIR/if_chain_style.rs:40:13 | LL | if true {} | ^^^^^^^^^^ | help: this `let` statement can also be in the `if_chain!` - --> $DIR/if_chain_style.rs:33:13 + --> $DIR/if_chain_style.rs:38:13 | LL | let x = ""; | ^^^^^^^^^^^ error: `if_chain!` only has one `if` - --> $DIR/if_chain_style.rs:29:5 + --> $DIR/if_chain_style.rs:34:5 | LL | / if_chain! { LL | | // single `if` condition @@ -59,13 +59,13 @@ LL | | } = note: this error originates in the macro `__if_chain` which comes from the expansion of the macro `if_chain` (in Nightly builds, run with -Z macro-backtrace for more info) error: `let` expression should be above the `if_chain!` - --> $DIR/if_chain_style.rs:40:9 + --> $DIR/if_chain_style.rs:45:9 | LL | let x = ""; | ^^^^^^^^^^^ error: this `if_chain!` can be merged with the outer `if_chain!` - --> $DIR/if_chain_style.rs:46:13 + --> $DIR/if_chain_style.rs:51:13 | LL | / if_chain! { LL | | if true; @@ -75,7 +75,7 @@ LL | | } | |_____________^ | help: these `let` statements can also be in the `if_chain!` - --> $DIR/if_chain_style.rs:43:13 + --> $DIR/if_chain_style.rs:48:13 | LL | / let x = ""; LL | | let x = ""; diff --git a/tests/ui-internal/interning_defined_symbol.fixed b/tests/ui-internal/interning_defined_symbol.fixed index eaea218e1288..a1a10c0798e3 100644 --- a/tests/ui-internal/interning_defined_symbol.fixed +++ b/tests/ui-internal/interning_defined_symbol.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)] #![feature(rustc_private)] diff --git a/tests/ui-internal/interning_defined_symbol.rs b/tests/ui-internal/interning_defined_symbol.rs index 7efebb8fae48..32dbfe5dcac2 100644 --- a/tests/ui-internal/interning_defined_symbol.rs +++ b/tests/ui-internal/interning_defined_symbol.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)] #![feature(rustc_private)] diff --git a/tests/ui-internal/invalid_msrv_attr_impl.fixed b/tests/ui-internal/invalid_msrv_attr_impl.fixed index 08634063a575..ac0752774f3f 100644 --- a/tests/ui-internal/invalid_msrv_attr_impl.fixed +++ b/tests/ui-internal/invalid_msrv_attr_impl.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/tests/ui-internal/invalid_msrv_attr_impl.rs b/tests/ui-internal/invalid_msrv_attr_impl.rs index f8af77e6d395..56f778621a44 100644 --- a/tests/ui-internal/invalid_msrv_attr_impl.rs +++ b/tests/ui-internal/invalid_msrv_attr_impl.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/tests/ui-internal/outer_expn_data.fixed b/tests/ui-internal/outer_expn_data.fixed index bb82faf0c904..d8a08bc99970 100644 --- a/tests/ui-internal/outer_expn_data.fixed +++ b/tests/ui-internal/outer_expn_data.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/tests/ui-internal/outer_expn_data.rs b/tests/ui-internal/outer_expn_data.rs index 187d468b3925..f7af0e9d8be2 100644 --- a/tests/ui-internal/outer_expn_data.rs +++ b/tests/ui-internal/outer_expn_data.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/tests/ui-internal/unnecessary_def_path.fixed b/tests/ui-internal/unnecessary_def_path.fixed index e474f370a5d1..fce24412f843 100644 --- a/tests/ui-internal/unnecessary_def_path.fixed +++ b/tests/ui-internal/unnecessary_def_path.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:paths.rs +//@run-rustfix +//@aux-build:paths.rs #![deny(clippy::internal)] #![feature(rustc_private)] diff --git a/tests/ui-internal/unnecessary_def_path.rs b/tests/ui-internal/unnecessary_def_path.rs index f17fed6c6530..b10bc9e46e2d 100644 --- a/tests/ui-internal/unnecessary_def_path.rs +++ b/tests/ui-internal/unnecessary_def_path.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:paths.rs +//@run-rustfix +//@aux-build:paths.rs #![deny(clippy::internal)] #![feature(rustc_private)] diff --git a/tests/ui-internal/unnecessary_symbol_str.fixed b/tests/ui-internal/unnecessary_symbol_str.fixed index 6033d06e4f63..b802de1cbc65 100644 --- a/tests/ui-internal/unnecessary_symbol_str.fixed +++ b/tests/ui-internal/unnecessary_symbol_str.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(rustc_private)] #![deny(clippy::internal)] #![allow( diff --git a/tests/ui-internal/unnecessary_symbol_str.rs b/tests/ui-internal/unnecessary_symbol_str.rs index 1bb5d55f0b60..c1bead5bdc98 100644 --- a/tests/ui-internal/unnecessary_symbol_str.rs +++ b/tests/ui-internal/unnecessary_symbol_str.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(rustc_private)] #![deny(clippy::internal)] #![allow( diff --git a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed index aa8b45b5fe7d..c90856845280 100644 --- a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed +++ b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed @@ -1,5 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::uninlined_format_args)] +#![allow(clippy::unnecessary_literal_unwrap)] fn main() { let local_i32 = 1; diff --git a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs index ad2e4863ee8e..661350c5c6d5 100644 --- a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs +++ b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs @@ -1,5 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::uninlined_format_args)] +#![allow(clippy::unnecessary_literal_unwrap)] fn main() { let local_i32 = 1; diff --git a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr index 1be0cda12fc1..eb1180e60b80 100644 --- a/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr +++ b/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr @@ -1,5 +1,5 @@ error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:9:5 + --> $DIR/uninlined_format_args.rs:10:5 | LL | println!("val='{}'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:10:5 + --> $DIR/uninlined_format_args.rs:11:5 | LL | println!("Hello {} is {:.*}", "x", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,20 +24,20 @@ LL + println!("Hello {} is {local_f64:.local_i32$}", "x"); | error: literal with an empty format string - --> $DIR/uninlined_format_args.rs:10:35 + --> $DIR/uninlined_format_args.rs:11:35 | LL | println!("Hello {} is {:.*}", "x", local_i32, local_f64); | ^^^ | = note: `-D clippy::print-literal` implied by `-D warnings` -help: try this +help: try | LL - println!("Hello {} is {:.*}", "x", local_i32, local_f64); LL + println!("Hello x is {:.*}", local_i32, local_f64); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:11:5 + --> $DIR/uninlined_format_args.rs:12:5 | LL | println!("Hello {} is {:.*}", local_i32, 5, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + println!("Hello {local_i32} is {local_f64:.*}", 5); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:12:5 + --> $DIR/uninlined_format_args.rs:13:5 | LL | println!("Hello {} is {2:.*}", local_i32, 5, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + println!("Hello {local_i32} is {local_f64:.*}", 5); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:13:5 + --> $DIR/uninlined_format_args.rs:14:5 | LL | println!("{}, {}", local_i32, local_opt.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs b/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs index fb5b1b193f84..33f7c8ba8042 100644 --- a/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs +++ b/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs @@ -1,4 +1,5 @@ #![warn(clippy::arithmetic_side_effects)] +#![allow(clippy::unnecessary_literal_unwrap)] use core::ops::{Add, Neg}; diff --git a/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr b/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr index ad89534aa1b0..4f98ca192311 100644 --- a/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr +++ b/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr @@ -1,5 +1,5 @@ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects_allowed.rs:68:13 + --> $DIR/arithmetic_side_effects_allowed.rs:69:13 | LL | let _ = Baz + Baz; | ^^^^^^^^^ @@ -7,49 +7,49 @@ LL | let _ = Baz + Baz; = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings` error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects_allowed.rs:79:13 + --> $DIR/arithmetic_side_effects_allowed.rs:80:13 | LL | let _ = 1i32 + Baz; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects_allowed.rs:82:13 + --> $DIR/arithmetic_side_effects_allowed.rs:83:13 | LL | let _ = 1i64 + Foo; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects_allowed.rs:86:13 + --> $DIR/arithmetic_side_effects_allowed.rs:87:13 | LL | let _ = 1i64 + Baz; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects_allowed.rs:97:13 + --> $DIR/arithmetic_side_effects_allowed.rs:98:13 | LL | let _ = Baz + 1i32; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects_allowed.rs:100:13 + --> $DIR/arithmetic_side_effects_allowed.rs:101:13 | LL | let _ = Foo + 1i64; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects_allowed.rs:104:13 + --> $DIR/arithmetic_side_effects_allowed.rs:105:13 | LL | let _ = Baz + 1i64; | ^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects_allowed.rs:113:13 + --> $DIR/arithmetic_side_effects_allowed.rs:114:13 | LL | let _ = -Bar; | ^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects_allowed.rs:115:13 + --> $DIR/arithmetic_side_effects_allowed.rs:116:13 | LL | let _ = -Baz; | ^^^^ diff --git a/tests/ui-toml/bad_toml/conf_bad_toml.rs b/tests/ui-toml/bad_toml/conf_bad_toml.rs index f328e4d9d04c..c69fcd300335 100644 --- a/tests/ui-toml/bad_toml/conf_bad_toml.rs +++ b/tests/ui-toml/bad_toml/conf_bad_toml.rs @@ -1 +1,3 @@ +//@error-in-other-file: error reading Clippy's configuration file: expected `.`, `=` + fn main() {} diff --git a/tests/ui-toml/bad_toml/conf_bad_toml.stderr b/tests/ui-toml/bad_toml/conf_bad_toml.stderr index 28c1a568a632..42871bf5e8a0 100644 --- a/tests/ui-toml/bad_toml/conf_bad_toml.stderr +++ b/tests/ui-toml/bad_toml/conf_bad_toml.stderr @@ -1,4 +1,16 @@ -error: error reading Clippy's configuration file `$DIR/clippy.toml`: expected an equals, found an identifier at line 1 column 4 +error: error reading Clippy's configuration file: expected `.`, `=` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/$DIR/clippy.toml:1:4 +======= + --> $DIR/clippy.toml:1:4 +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + --> $DIR/$DIR/clippy.toml:1:4 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | fn this_is_obviously(not: a, toml: file) { + | ^ error: aborting due to previous error diff --git a/tests/ui-toml/bad_toml_type/conf_bad_type.rs b/tests/ui-toml/bad_toml_type/conf_bad_type.rs index f328e4d9d04c..688c92d8717d 100644 --- a/tests/ui-toml/bad_toml_type/conf_bad_type.rs +++ b/tests/ui-toml/bad_toml_type/conf_bad_type.rs @@ -1 +1,3 @@ +//@error-in-other-file: invalid type: integer `42`, expected a sequence + fn main() {} diff --git a/tests/ui-toml/bad_toml_type/conf_bad_type.stderr b/tests/ui-toml/bad_toml_type/conf_bad_type.stderr index e3ec60192040..8dca058bb4d8 100644 --- a/tests/ui-toml/bad_toml_type/conf_bad_type.stderr +++ b/tests/ui-toml/bad_toml_type/conf_bad_type.stderr @@ -1,4 +1,16 @@ -error: error reading Clippy's configuration file `$DIR/clippy.toml`: invalid type: integer `42`, expected a sequence for key `disallowed-names` +error: error reading Clippy's configuration file: invalid type: integer `42`, expected a sequence +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/$DIR/clippy.toml:1:20 +======= + --> $DIR/clippy.toml:1:20 +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + --> $DIR/$DIR/clippy.toml:1:20 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | disallowed-names = 42 + | ^^ error: aborting due to previous error diff --git a/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr b/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr index 630bad07c5b7..528997f33338 100644 --- a/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr +++ b/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr @@ -1,6 +1,30 @@ -warning: error reading Clippy's configuration file `$DIR/clippy.toml`: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead +warning: error reading Clippy's configuration file: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/$DIR/clippy.toml:2:1 +======= + --> $DIR/clippy.toml:2:1 +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + --> $DIR/$DIR/clippy.toml:2:1 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | cyclomatic-complexity-threshold = 2 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: error reading Clippy's configuration file `$DIR/clippy.toml`: deprecated field `blacklisted-names`. Please use `disallowed-names` instead +warning: error reading Clippy's configuration file: deprecated field `blacklisted-names`. Please use `disallowed-names` instead +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/$DIR/clippy.toml:3:1 +======= + --> $DIR/clippy.toml:3:1 +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + --> $DIR/$DIR/clippy.toml:3:1 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | blacklisted-names = [ "..", "wibble" ] + | ^^^^^^^^^^^^^^^^^ error: the function has a cognitive complexity of (3/2) --> $DIR/conf_deprecated_key.rs:6:4 diff --git a/tests/ui-toml/dbg_macro/dbg_macro.rs b/tests/ui-toml/dbg_macro/dbg_macro.rs index 5d9ce18f631b..21e4fce26e4e 100644 --- a/tests/ui-toml/dbg_macro/dbg_macro.rs +++ b/tests/ui-toml/dbg_macro/dbg_macro.rs @@ -1,4 +1,4 @@ -// compile-flags: --test +//@compile-flags: --test #![warn(clippy::dbg_macro)] fn foo(n: u32) -> u32 { diff --git a/tests/ui-toml/disallowed_macros/disallowed_macros.rs b/tests/ui-toml/disallowed_macros/disallowed_macros.rs index 2bb5376076e2..ba919b487885 100644 --- a/tests/ui-toml/disallowed_macros/disallowed_macros.rs +++ b/tests/ui-toml/disallowed_macros/disallowed_macros.rs @@ -1,4 +1,4 @@ -// aux-build:macros.rs +//@aux-build:macros.rs #![allow(unused)] diff --git a/tests/ui-toml/duplicated_keys/clippy.toml b/tests/ui-toml/duplicated_keys/clippy.toml index 63a893cc6c79..55789afc1b71 100644 --- a/tests/ui-toml/duplicated_keys/clippy.toml +++ b/tests/ui-toml/duplicated_keys/clippy.toml @@ -1,5 +1,2 @@ cognitive-complexity-threshold = 2 -# This is the deprecated name for the same key -cyclomatic-complexity-threshold = 3 -# Check we get duplication warning regardless of order cognitive-complexity-threshold = 4 diff --git a/tests/ui-toml/duplicated_keys/duplicated_keys.rs b/tests/ui-toml/duplicated_keys/duplicated_keys.rs index f328e4d9d04c..187775545ed7 100644 --- a/tests/ui-toml/duplicated_keys/duplicated_keys.rs +++ b/tests/ui-toml/duplicated_keys/duplicated_keys.rs @@ -1 +1,3 @@ +//@error-in-other-file: duplicate key `cognitive-complexity-threshold` + fn main() {} diff --git a/tests/ui-toml/duplicated_keys/duplicated_keys.stderr b/tests/ui-toml/duplicated_keys/duplicated_keys.stderr index d99490a242d4..c90bc2dfd8c5 100644 --- a/tests/ui-toml/duplicated_keys/duplicated_keys.stderr +++ b/tests/ui-toml/duplicated_keys/duplicated_keys.stderr @@ -1,8 +1,16 @@ -error: error reading Clippy's configuration file `$DIR/clippy.toml`: duplicate field `cognitive_complexity_threshold` (provided as `cyclomatic_complexity_threshold`) +error: error reading Clippy's configuration file: duplicate key `cognitive-complexity-threshold` in document root +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/$DIR/clippy.toml:2:1 +======= + --> $DIR/clippy.toml:2:1 +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + --> $DIR/$DIR/clippy.toml:2:1 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | cognitive-complexity-threshold = 4 + | ^ -error: error reading Clippy's configuration file `$DIR/clippy.toml`: duplicate field `cognitive-complexity-threshold` - -warning: error reading Clippy's configuration file `$DIR/clippy.toml`: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to previous error diff --git a/tests/ui-toml/duplicated_keys_deprecated/clippy.toml b/tests/ui-toml/duplicated_keys_deprecated/clippy.toml new file mode 100644 index 000000000000..7932c43ebd21 --- /dev/null +++ b/tests/ui-toml/duplicated_keys_deprecated/clippy.toml @@ -0,0 +1,3 @@ +cognitive-complexity-threshold = 2 +# This is the deprecated name for the same key +cyclomatic-complexity-threshold = 3 diff --git a/tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.rs b/tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.rs new file mode 100644 index 000000000000..f328e4d9d04c --- /dev/null +++ b/tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.stderr b/tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.stderr new file mode 100644 index 000000000000..c3abffd46d2f --- /dev/null +++ b/tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.stderr @@ -0,0 +1,30 @@ +error: error reading Clippy's configuration file: duplicate field `cognitive_complexity_threshold` (provided as `cyclomatic_complexity_threshold`) +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/$DIR/clippy.toml:3:1 +======= + --> $DIR/clippy.toml:3:1 +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + --> $DIR/$DIR/clippy.toml:3:1 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | cyclomatic-complexity-threshold = 3 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: error reading Clippy's configuration file: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/$DIR/clippy.toml:3:1 +======= + --> $DIR/clippy.toml:3:1 +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + --> $DIR/$DIR/clippy.toml:3:1 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | cyclomatic-complexity-threshold = 3 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui-toml/duplicated_keys_deprecated_2/clippy.toml b/tests/ui-toml/duplicated_keys_deprecated_2/clippy.toml new file mode 100644 index 000000000000..53c634b727ed --- /dev/null +++ b/tests/ui-toml/duplicated_keys_deprecated_2/clippy.toml @@ -0,0 +1,4 @@ +# This is the deprecated name for cognitive-complexity-threshold +cyclomatic-complexity-threshold = 3 +# Check we get duplication warning regardless of order +cognitive-complexity-threshold = 4 diff --git a/tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.rs b/tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.rs new file mode 100644 index 000000000000..f328e4d9d04c --- /dev/null +++ b/tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.stderr b/tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.stderr new file mode 100644 index 000000000000..428cd4c3c190 --- /dev/null +++ b/tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.stderr @@ -0,0 +1,30 @@ +error: error reading Clippy's configuration file: duplicate field `cognitive-complexity-threshold` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/$DIR/clippy.toml:4:1 +======= + --> $DIR/clippy.toml:4:1 +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + --> $DIR/$DIR/clippy.toml:4:1 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | cognitive-complexity-threshold = 4 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: error reading Clippy's configuration file: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/$DIR/clippy.toml:2:1 +======= + --> $DIR/clippy.toml:2:1 +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + --> $DIR/$DIR/clippy.toml:2:1 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | cyclomatic-complexity-threshold = 3 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui-toml/excessive_nesting/auxiliary/proc_macros.rs b/tests/ui-toml/excessive_nesting/auxiliary/proc_macros.rs new file mode 100644 index 000000000000..81626f13e485 --- /dev/null +++ b/tests/ui-toml/excessive_nesting/auxiliary/proc_macros.rs @@ -0,0 +1,487 @@ +<<<<<<< HEAD +<<<<<<< HEAD +// NOTE: Copied from `ui/auxiliary/proc_macros.rs`, couldn't get `../` to work for some reason + +#![feature(let_chains)] +#![feature(proc_macro_span)] +#![allow(clippy::excessive_nesting, dead_code)] +======= +//@compile-flags: --emit=link +//@no-prefer-dynamic + +======= +>>>>>>> 5bd97ac17 (Update tests) +// NOTE: Copied from `ui/auxiliary/proc_macros.rs`, couldn't get `../` to work for some reason + +#![feature(let_chains)] +#![feature(proc_macro_span)] +<<<<<<< HEAD +#![allow(dead_code)] +>>>>>>> 5da34559e (Check if from proc macro and better tests) +======= +#![allow(clippy::excessive_nesting, dead_code)] +>>>>>>> 6afb3555d (remove revisions) + +extern crate proc_macro; + +use core::mem; +use proc_macro::token_stream::IntoIter; +use proc_macro::Delimiter::{self, Brace, Parenthesis}; +use proc_macro::Spacing::{self, Alone, Joint}; +use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree as TT}; + +type Result = core::result::Result; + +/// Make a `compile_error!` pointing to the given span. +fn make_error(msg: &str, span: Span) -> TokenStream { + TokenStream::from_iter([ + TT::Ident(Ident::new("compile_error", span)), + TT::Punct(punct_with_span('!', Alone, span)), + TT::Group({ + let mut msg = Literal::string(msg); + msg.set_span(span); + group_with_span(Parenthesis, TokenStream::from_iter([TT::Literal(msg)]), span) + }), + ]) +} + +fn expect_tt(tt: Option, f: impl FnOnce(TT) -> Option, expected: &str, span: Span) -> Result { + match tt { + None => Err(make_error( + &format!("unexpected end of input, expected {expected}"), + span, + )), + Some(tt) => { + let span = tt.span(); + match f(tt) { + Some(x) => Ok(x), + None => Err(make_error(&format!("unexpected token, expected {expected}"), span)), + } + }, + } +} + +fn punct_with_span(c: char, spacing: Spacing, span: Span) -> Punct { + let mut p = Punct::new(c, spacing); + p.set_span(span); + p +} + +fn group_with_span(delimiter: Delimiter, stream: TokenStream, span: Span) -> Group { + let mut g = Group::new(delimiter, stream); + g.set_span(span); + g +} + +/// Token used to escape the following token from the macro's span rules. +const ESCAPE_CHAR: char = '$'; + +/// Takes a single token followed by a sequence of tokens. Returns the sequence of tokens with their +/// span set to that of the first token. Tokens may be escaped with either `#ident` or `#(tokens)`. +#[proc_macro] +pub fn with_span(input: TokenStream) -> TokenStream { + let mut iter = input.into_iter(); + let span = iter.next().unwrap().span(); + let mut res = TokenStream::new(); + if let Err(e) = write_with_span(span, iter, &mut res) { + e + } else { + res + } +} + +/// Takes a sequence of tokens and return the tokens with the span set such that they appear to be +/// from an external macro. Tokens may be escaped with either `#ident` or `#(tokens)`. +#[proc_macro] +pub fn external(input: TokenStream) -> TokenStream { + let mut res = TokenStream::new(); + if let Err(e) = write_with_span(Span::mixed_site(), input.into_iter(), &mut res) { + e + } else { + res + } +} + +/// Copies all the tokens, replacing all their spans with the given span. Tokens can be escaped +/// either by `#ident` or `#(tokens)`. +fn write_with_span(s: Span, mut input: IntoIter, out: &mut TokenStream) -> Result<()> { + while let Some(tt) = input.next() { + match tt { + TT::Punct(p) if p.as_char() == ESCAPE_CHAR => { + expect_tt( + input.next(), + |tt| match tt { + tt @ (TT::Ident(_) | TT::Literal(_)) => { + out.extend([tt]); + Some(()) + }, + TT::Punct(mut p) if p.as_char() == ESCAPE_CHAR => { + p.set_span(s); + out.extend([TT::Punct(p)]); + Some(()) + }, + TT::Group(g) if g.delimiter() == Parenthesis => { + out.extend([TT::Group(group_with_span(Delimiter::None, g.stream(), g.span()))]); + Some(()) + }, + _ => None, + }, + "an ident, a literal, or parenthesized tokens", + p.span(), + )?; + }, + TT::Group(g) => { + let mut stream = TokenStream::new(); + write_with_span(s, g.stream().into_iter(), &mut stream)?; + out.extend([TT::Group(group_with_span(g.delimiter(), stream, s))]); + }, + mut tt => { + tt.set_span(s); + out.extend([tt]); + }, + } + } + Ok(()) +} + +/// Within the item this attribute is attached to, an `inline!` macro is available which expands the +/// contained tokens as though they came from a macro expansion. +/// +/// Within the `inline!` macro, any token preceded by `$` is passed as though it were an argument +/// with an automatically chosen fragment specifier. `$ident` will be passed as `ident`, `$1` or +/// `$"literal"` will be passed as `literal`, `$'lt` will be passed as `lifetime`, and `$(...)` will +/// pass the contained tokens as a `tt` sequence (the wrapping parenthesis are removed). If another +/// specifier is required it can be specified within parenthesis like `$(@expr ...)`. This will +/// expand the remaining tokens as a single argument. +/// +/// Multiple `inline!` macros may be nested within each other. This will expand as nested macro +/// calls. However, any arguments will be passed as though they came from the outermost context. +#[proc_macro_attribute] +pub fn inline_macros(args: TokenStream, input: TokenStream) -> TokenStream { + let mut args = args.into_iter(); + let mac_name = match args.next() { + Some(TT::Ident(name)) => Some(name), + Some(tt) => { + return make_error( + "unexpected argument, expected either an ident or no arguments", + tt.span(), + ); + }, + None => None, + }; + if let Some(tt) = args.next() { + return make_error( + "unexpected argument, expected either an ident or no arguments", + tt.span(), + ); + }; + + let mac_name = if let Some(mac_name) = mac_name { + Ident::new(&format!("__inline_mac_{mac_name}"), Span::call_site()) + } else { + let mut input = match LookaheadIter::new(input.clone().into_iter()) { + Some(x) => x, + None => return input, + }; + loop { + match input.next() { + None => break Ident::new("__inline_mac", Span::call_site()), + Some(TT::Ident(kind)) => match &*kind.to_string() { + "impl" => break Ident::new("__inline_mac_impl", Span::call_site()), + kind @ ("struct" | "enum" | "union" | "fn" | "mod" | "trait" | "type" | "const" | "static") => { + if let TT::Ident(name) = &input.tt { + break Ident::new(&format!("__inline_mac_{kind}_{name}"), Span::call_site()); + } else { + break Ident::new(&format!("__inline_mac_{kind}"), Span::call_site()); + } + }, + _ => {}, + }, + _ => {}, + } + } + }; + + let mut expander = Expander::default(); + let mut mac = MacWriter::new(mac_name); + if let Err(e) = expander.expand(input.into_iter(), &mut mac) { + return e; + } + let mut out = TokenStream::new(); + mac.finish(&mut out); + out.extend(expander.expn); + out +} + +/// Wraps a `TokenStream` iterator with a single token lookahead. +struct LookaheadIter { + tt: TT, + iter: IntoIter, +} +impl LookaheadIter { + fn new(mut iter: IntoIter) -> Option { + iter.next().map(|tt| Self { tt, iter }) + } + + /// Get's the lookahead token, replacing it with the next token in the stream. + /// Note: If there isn't a next token, this will not return the lookahead token. + fn next(&mut self) -> Option { + self.iter.next().map(|tt| mem::replace(&mut self.tt, tt)) + } +} + +/// Builds the macro used to implement all the `inline!` macro calls. +struct MacWriter { + name: Ident, + macros: TokenStream, + next_idx: usize, +} +impl MacWriter { + fn new(name: Ident) -> Self { + Self { + name, + macros: TokenStream::new(), + next_idx: 0, + } + } + + /// Inserts a new `inline!` call. + fn insert(&mut self, name_span: Span, bang_span: Span, body: Group, expander: &mut Expander) -> Result<()> { + let idx = self.next_idx; + self.next_idx += 1; + + let mut inner = Expander::for_arm(idx); + inner.expand(body.stream().into_iter(), self)?; + let new_arm = inner.arm.unwrap(); + + self.macros.extend([ + TT::Group(Group::new(Parenthesis, new_arm.args_def)), + TT::Punct(Punct::new('=', Joint)), + TT::Punct(Punct::new('>', Alone)), + TT::Group(Group::new(Parenthesis, inner.expn)), + TT::Punct(Punct::new(';', Alone)), + ]); + + expander.expn.extend([ + TT::Ident({ + let mut name = self.name.clone(); + name.set_span(name_span); + name + }), + TT::Punct(punct_with_span('!', Alone, bang_span)), + ]); + let mut call_body = TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]); + if let Some(arm) = expander.arm.as_mut() { + if !new_arm.args.is_empty() { + arm.add_sub_args(new_arm.args, &mut call_body); + } + } else { + call_body.extend(new_arm.args); + } + let mut g = Group::new(body.delimiter(), call_body); + g.set_span(body.span()); + expander.expn.extend([TT::Group(g)]); + Ok(()) + } + + /// Creates the macro definition. + fn finish(self, out: &mut TokenStream) { + if self.next_idx != 0 { + out.extend([ + TT::Ident(Ident::new("macro_rules", Span::call_site())), + TT::Punct(Punct::new('!', Alone)), + TT::Ident(self.name), + TT::Group(Group::new(Brace, self.macros)), + ]) + } + } +} + +struct MacroArm { + args_def: TokenStream, + args: Vec, +} +impl MacroArm { + fn add_single_arg_def(&mut self, kind: &str, dollar_span: Span, arg_span: Span, out: &mut TokenStream) { + let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site()); + self.args_def.extend([ + TT::Punct(Punct::new('$', Alone)), + TT::Ident(name.clone()), + TT::Punct(Punct::new(':', Alone)), + TT::Ident(Ident::new(kind, Span::call_site())), + ]); + name.set_span(arg_span); + out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]); + } + + fn add_parenthesized_arg_def(&mut self, kind: Ident, dollar_span: Span, arg_span: Span, out: &mut TokenStream) { + let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site()); + self.args_def.extend([TT::Group(Group::new( + Parenthesis, + TokenStream::from_iter([ + TT::Punct(Punct::new('$', Alone)), + TT::Ident(name.clone()), + TT::Punct(Punct::new(':', Alone)), + TT::Ident(kind), + ]), + ))]); + name.set_span(arg_span); + out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]); + } + + fn add_multi_arg_def(&mut self, dollar_span: Span, arg_span: Span, out: &mut TokenStream) { + let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site()); + self.args_def.extend([TT::Group(Group::new( + Parenthesis, + TokenStream::from_iter([ + TT::Punct(Punct::new('$', Alone)), + TT::Group(Group::new( + Parenthesis, + TokenStream::from_iter([ + TT::Punct(Punct::new('$', Alone)), + TT::Ident(name.clone()), + TT::Punct(Punct::new(':', Alone)), + TT::Ident(Ident::new("tt", Span::call_site())), + ]), + )), + TT::Punct(Punct::new('*', Alone)), + ]), + ))]); + name.set_span(arg_span); + out.extend([ + TT::Punct(punct_with_span('$', Alone, dollar_span)), + TT::Group(group_with_span( + Parenthesis, + TokenStream::from_iter([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]), + dollar_span, + )), + TT::Punct(punct_with_span('*', Alone, dollar_span)), + ]); + } + + fn add_arg(&mut self, dollar_span: Span, tt: TT, input: &mut IntoIter, out: &mut TokenStream) -> Result<()> { + match tt { + TT::Punct(p) if p.as_char() == ESCAPE_CHAR => out.extend([TT::Punct(p)]), + TT::Punct(p) if p.as_char() == '\'' && p.spacing() == Joint => { + let lt_name = expect_tt( + input.next(), + |tt| match tt { + TT::Ident(x) => Some(x), + _ => None, + }, + "lifetime name", + p.span(), + )?; + let arg_span = p.span().join(lt_name.span()).unwrap_or(p.span()); + self.add_single_arg_def("lifetime", dollar_span, arg_span, out); + self.args.extend([TT::Punct(p), TT::Ident(lt_name)]); + }, + TT::Ident(x) => { + self.add_single_arg_def("ident", dollar_span, x.span(), out); + self.args.push(TT::Ident(x)); + }, + TT::Literal(x) => { + self.add_single_arg_def("literal", dollar_span, x.span(), out); + self.args.push(TT::Literal(x)); + }, + TT::Group(g) if g.delimiter() == Parenthesis => { + let mut inner = g.stream().into_iter(); + if let Some(TT::Punct(p)) = inner.next() + && p.as_char() == '@' + { + let kind = expect_tt( + inner.next(), + |tt| match tt { + TT::Ident(kind) => Some(kind), + _ => None, + }, + "a macro fragment specifier", + p.span(), + )?; + self.add_parenthesized_arg_def(kind, dollar_span, g.span(), out); + self.args.push(TT::Group(group_with_span(Parenthesis, inner.collect(), g.span()))) + } else { + self.add_multi_arg_def(dollar_span, g.span(), out); + self.args.push(TT::Group(g)); + } + }, + tt => return Err(make_error("unsupported escape", tt.span())), + }; + Ok(()) + } + + fn add_sub_args(&mut self, args: Vec, out: &mut TokenStream) { + self.add_multi_arg_def(Span::call_site(), Span::call_site(), out); + self.args + .extend([TT::Group(Group::new(Parenthesis, TokenStream::from_iter(args)))]); + } +} + +#[derive(Default)] +struct Expander { + arm: Option, + expn: TokenStream, +} +impl Expander { + fn for_arm(idx: usize) -> Self { + Self { + arm: Some(MacroArm { + args_def: TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]), + args: Vec::new(), + }), + expn: TokenStream::new(), + } + } + + fn write_tt(&mut self, tt: TT, mac: &mut MacWriter) -> Result<()> { + match tt { + TT::Group(g) => { + let outer = mem::take(&mut self.expn); + self.expand(g.stream().into_iter(), mac)?; + let inner = mem::replace(&mut self.expn, outer); + self.expn + .extend([TT::Group(group_with_span(g.delimiter(), inner, g.span()))]); + }, + tt => self.expn.extend([tt]), + } + Ok(()) + } + + fn expand(&mut self, input: IntoIter, mac: &mut MacWriter) -> Result<()> { + let Some(mut input) = LookaheadIter::new(input) else { + return Ok(()); + }; + while let Some(tt) = input.next() { + if let TT::Punct(p) = &tt + && p.as_char() == ESCAPE_CHAR + && let Some(arm) = self.arm.as_mut() + { + arm.add_arg(p.span(), mem::replace(&mut input.tt, tt), &mut input.iter, &mut self.expn)?; + if input.next().is_none() { + return Ok(()); + } + } else if let TT::Punct(p) = &input.tt + && p.as_char() == '!' + && let TT::Ident(name) = &tt + && name.to_string() == "inline" + { + let g = expect_tt( + input.iter.next(), + |tt| match tt { + TT::Group(g) => Some(g), + _ => None, + }, + "macro arguments", + p.span(), + )?; + mac.insert(name.span(), p.span(), g, self)?; + if input.next().is_none() { + return Ok(()); + } + } else { + self.write_tt(tt, mac)?; + } + } + self.write_tt(input.tt, mac) + } +} diff --git a/tests/ui-toml/excessive_nesting/clippy.toml b/tests/ui-toml/excessive_nesting/clippy.toml new file mode 100644 index 000000000000..e60ac978cac9 --- /dev/null +++ b/tests/ui-toml/excessive_nesting/clippy.toml @@ -0,0 +1 @@ +excessive-nesting-threshold = 4 diff --git a/tests/ui-toml/excessive_nesting/excessive_nesting.rs b/tests/ui-toml/excessive_nesting/excessive_nesting.rs new file mode 100644 index 000000000000..79541f2e23ca --- /dev/null +++ b/tests/ui-toml/excessive_nesting/excessive_nesting.rs @@ -0,0 +1,291 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:macro_rules.rs +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= +//@revisions: below default +//@[below] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/excessive_nesting/below +======= +//@revisions: set default +//@[set] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/excessive_nesting/set +>>>>>>> 725399a17 (move to `complexity` but don't lint by default) +//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/excessive_nesting/default +>>>>>>> 378d77584 (work with lint attributes) +======= +//@aux-build:proc_macros.rs +<<<<<<< HEAD +//@revisions: set above +//@[set] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/excessive_nesting/set +//@[above] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/excessive_nesting/above +>>>>>>> 5da34559e (Check if from proc macro and better tests) +======= +>>>>>>> 6afb3555d (remove revisions) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) +#![rustfmt::skip] +#![feature(custom_inner_attributes)] +#![allow(unused)] +#![allow(clippy::let_and_return)] +#![allow(clippy::redundant_closure_call)] +#![allow(clippy::no_effect)] +#![allow(clippy::unnecessary_operation)] +#![allow(clippy::never_loop)] +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::needless_if)] +======= +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= +#![allow(clippy::needless_if)] +>>>>>>> 7ba904245 (make cargo test pass) +#![warn(clippy::excessive_nesting)] +#![allow(clippy::collapsible_if)] + +#[macro_use] +<<<<<<< HEAD +<<<<<<< HEAD +extern crate proc_macros; +======= +extern crate macro_rules; +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= +extern crate proc_macros; +>>>>>>> 5da34559e (Check if from proc macro and better tests) + +static X: u32 = { + let x = { + let y = { + let z = { + let w = { 3 }; + w + }; + z + }; + y + }; + x +}; + +macro_rules! xx { + () => {{ + { + { + { + { + { + { + { + { + { + { +<<<<<<< HEAD +<<<<<<< HEAD + println!("ehe"); // should not lint +======= + println!("ehe"); +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + println!("ehe"); // should not lint +>>>>>>> 493a23e95 (check non-inline modules, ignore all macros) + } + } + } + } + } + } + } + } + } + } + }}; +} + +struct A; + +impl A { + pub fn a(&self, v: u32) { + struct B; + + impl B { + pub fn b() { + struct C; + + impl C { + pub fn c() {} + } + } + } + } +} + +struct D { d: u32 } + +trait Lol { + fn lmao() { + fn bb() { + fn cc() { +<<<<<<< HEAD +<<<<<<< HEAD + let x = { 1 }; // not a warning, but cc is +======= + let x = { 1 }; // not a warning +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + let x = { 1 }; // not a warning, but cc is +>>>>>>> 88143ac29 (decided against reinventing the wheel) + } + + let x = { 1 }; // warning + } + } +} + +<<<<<<< HEAD +<<<<<<< HEAD +#[allow(clippy::excessive_nesting)] +fn l() {{{{{{{{{}}}}}}}}} + +======= +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= +#[allow(clippy::excessive_nesting)] +fn l() {{{{{{{{{}}}}}}}}} + +>>>>>>> 378d77584 (work with lint attributes) +use a::{b::{c::{d::{e::{f::{}}}}}}; // should not lint + +pub mod a { + pub mod b { + pub mod c { + pub mod d { + pub mod e { + pub mod f {} +<<<<<<< HEAD +<<<<<<< HEAD + } // not here + } // only warning should be here +======= + } + } +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + } // not here + } // only warning should be here +>>>>>>> 88143ac29 (decided against reinventing the wheel) + } + } +} + +fn a_but_not(v: u32) {} + +fn main() { + let a = A; + + a_but_not({{{{{{{{0}}}}}}}}); + a.a({{{{{{{{{0}}}}}}}}}); + (0, {{{{{{{1}}}}}}}); + + if true { + if true { + if true { + if true { + if true { + + } + } + } + } + } + + let y = (|| { + let x = (|| { + let y = (|| { + let z = (|| { + let w = { 3 }; + w + })(); + z + })(); + y + })(); + x + })(); + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5da34559e (Check if from proc macro and better tests) + external! { {{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}} }; // ensure this isn't linted in external macros + with_span! { span {{{{{{{{{{{{}}}}}}}}}}}} }; // don't lint for proc macros + xx!(); // ensure this is never linted + let boo = true; + !{boo as u32 + !{boo as u32 + !{boo as u32}}}; + + // this is a mess, but that's intentional +======= + excessive_nesting!(); // ensure this isn't linted in external macros + xx!(); // ensure this is never linted + let boo = true; + !{boo as u32 + !{boo as u32 + !{boo as u32}}}; + +<<<<<<< HEAD +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + // this is a mess, but that's intentional +>>>>>>> 88143ac29 (decided against reinventing the wheel) + let mut y = 1; + y += {{{{{5}}}}}; + let z = y + {{{{{{{{{5}}}}}}}}}; + [0, {{{{{{{{{{0}}}}}}}}}}]; + let mut xx = [0; {{{{{{{{100}}}}}}}}]; + xx[{{{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}}}]; + &mut {{{{{{{{{{y}}}}}}}}}}; + + for i in {{{{xx}}}} {{{{{{{{}}}}}}}} + + while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} + + while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} + + let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} }; + + {{{{1;}}}}..{{{{{{3}}}}}}; + {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; + ..{{{{{{{5}}}}}}}; + ..={{{{{3}}}}}; + {{{{{1;}}}}}..; + + loop { break {{{{1}}}} }; + loop {{{{{{}}}}}} + + match {{{{{{true}}}}}} { + true => {{{{}}}}, + false => {{{{}}}}, + } + + { + { + { + { + println!("warning! :)"); + } + } + } + } +} + +async fn b() -> u32 { + async fn c() -> u32 {{{{{{{0}}}}}}} + + c().await +} + +async fn a() { + {{{{b().await}}}}; +} diff --git a/tests/ui-toml/excessive_nesting/excessive_nesting.stderr b/tests/ui-toml/excessive_nesting/excessive_nesting.stderr new file mode 100644 index 000000000000..397dd7878dba --- /dev/null +++ b/tests/ui-toml/excessive_nesting/excessive_nesting.stderr @@ -0,0 +1,743 @@ +error: this block is too nested +<<<<<<< HEAD +<<<<<<< HEAD:tests/ui-toml/excessive_nesting/excessive_nesting.above.stderr +<<<<<<< HEAD:tests/ui-toml/excessive_nesting/excessive_nesting.stderr +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 7ba904245 (make cargo test pass) + --> $DIR/excessive_nesting.rs:21:25 + | +LL | let w = { 3 }; + | ^^^^^ +======= + --> $DIR/auxiliary/mod.rs:6:13 + | +LL | / mod d { +LL | | mod e {} +LL | | } + | |_____________^ +>>>>>>> 493a23e95 (check non-inline modules, ignore all macros) +======= + --> $DIR/excessive_nesting.rs:23:25 +======= + --> $DIR/excessive_nesting.rs:20:25 +>>>>>>> 6afb3555d (remove revisions):tests/ui-toml/excessive_nesting/excessive_nesting.stderr + | +LL | let w = { 3 }; + | ^^^^^ +>>>>>>> 5da34559e (Check if from proc macro and better tests):tests/ui-toml/excessive_nesting/excessive_nesting.above.stderr + | + = help: try refactoring your code to minimize nesting + = note: `-D clippy::excessive-nesting` implied by `-D warnings` + +error: this block is too nested +<<<<<<< HEAD +<<<<<<< HEAD:tests/ui-toml/excessive_nesting/excessive_nesting.above.stderr +<<<<<<< HEAD:tests/ui-toml/excessive_nesting/excessive_nesting.stderr +<<<<<<< HEAD +======= +>>>>>>> 7ba904245 (make cargo test pass) + --> $DIR/excessive_nesting.rs:67:17 + | +LL | / impl C { +LL | | pub fn c() {} +LL | | } + | |_________________^ +======= + --> $DIR/auxiliary/mod.rs:15:7 + | +LL | {{{}}} + | ^^ +>>>>>>> 493a23e95 (check non-inline modules, ignore all macros) + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested +<<<<<<< HEAD + --> $DIR/excessive_nesting.rs:81:25 + | +LL | let x = { 1 }; // not a warning, but cc is + | ^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:98:17 + | +LL | / pub mod e { +LL | | pub mod f {} +LL | | } // not here + | |_________________^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:111:18 + | +LL | a_but_not({{{{{{{{0}}}}}}}}); + | ^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:112:12 + | +LL | a.a({{{{{{{{{0}}}}}}}}}); + | ^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:113:12 + | +LL | (0, {{{{{{{1}}}}}}}); + | ^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:118:25 + | +LL | if true { + | _________________________^ +======= + --> $DIR/excessive_nesting.rs:19:21 +======= + --> $DIR/excessive_nesting.rs:21:21 +>>>>>>> 493a23e95 (check non-inline modules, ignore all macros) + | +LL | let z = { + | _____________________^ +LL | | let w = { 3 }; +LL | | w +LL | | }; + | |_____________^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:65:24 + | +LL | pub fn b() { + | ________________________^ +LL | | struct C; +LL | | +LL | | impl C { +======= + --> $DIR/excessive_nesting.rs:69:17 +======= + --> $DIR/excessive_nesting.rs:66:17 +>>>>>>> 6afb3555d (remove revisions):tests/ui-toml/excessive_nesting/excessive_nesting.stderr + | +LL | / impl C { +>>>>>>> 5da34559e (Check if from proc macro and better tests):tests/ui-toml/excessive_nesting/excessive_nesting.above.stderr +LL | | pub fn c() {} +LL | | } + | |_________________^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:81:25 + | +LL | let x = { 1 }; // not a warning, but cc is + | ^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:98:17 + | +LL | / pub mod e { +LL | | pub mod f {} +LL | | } // not here + | |_________________^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:111:18 + | +LL | a_but_not({{{{{{{{0}}}}}}}}); + | ^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:112:12 + | +LL | a.a({{{{{{{{{0}}}}}}}}}); + | ^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:113:12 + | +LL | (0, {{{{{{{1}}}}}}}); + | ^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:118:25 + | +<<<<<<< HEAD:tests/ui-toml/excessive_nesting/excessive_nesting.stderr +LL | if true { + | _____________________^ +LL | | if true { +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= +LL | if true { + | _________________________^ +>>>>>>> 5da34559e (Check if from proc macro and better tests):tests/ui-toml/excessive_nesting/excessive_nesting.above.stderr +LL | | if true { +LL | | +LL | | } +LL | | } +<<<<<<< HEAD:tests/ui-toml/excessive_nesting/excessive_nesting.stderr +<<<<<<< HEAD + | |_________________^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested +<<<<<<< HEAD +<<<<<<< HEAD:tests/ui-toml/excessive_nesting/excessive_nesting.above.stderr + --> $DIR/excessive_nesting.rs:130:29 + | +LL | let z = (|| { + | _____________________________^ +LL | | let w = { 3 }; +LL | | w +LL | | })(); + | |_________________^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:149:13 + | +LL | y += {{{{{5}}}}}; + | ^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:150:20 + | +LL | let z = y + {{{{{{{{{5}}}}}}}}}; + | ^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:151:12 + | +LL | [0, {{{{{{{{{{0}}}}}}}}}}]; + | ^^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:152:25 + | +LL | let mut xx = [0; {{{{{{{{100}}}}}}}}]; + | ^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:153:11 + | +LL | xx[{{{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}}}]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting +======= +LL | | } + | |_____________^ +======= + | |_________________^ +>>>>>>> 5da34559e (Check if from proc macro and better tests):tests/ui-toml/excessive_nesting/excessive_nesting.above.stderr + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:132:29 +======= + --> $DIR/excessive_nesting.rs:129:29 +>>>>>>> 6afb3555d (remove revisions):tests/ui-toml/excessive_nesting/excessive_nesting.stderr +======= + --> $DIR/excessive_nesting.rs:130:29 +>>>>>>> 7ba904245 (make cargo test pass) + | +LL | let z = (|| { + | _____________________________^ +LL | | let w = { 3 }; +LL | | w +LL | | })(); + | |_________________^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:149:13 + | +LL | y += {{{{{5}}}}}; + | ^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:150:20 + | +LL | let z = y + {{{{{{{{{5}}}}}}}}}; + | ^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:151:12 + | +LL | [0, {{{{{{{{{{0}}}}}}}}}}]; + | ^^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:152:25 + | +LL | let mut xx = [0; {{{{{{{{100}}}}}}}}]; + | ^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:153:11 + | +LL | xx[{{{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}}}]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:154:13 + | +LL | &mut {{{{{{{{{{y}}}}}}}}}}; + | ^^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:156:17 + | +LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} + | ^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:156:28 + | +LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} + | ^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:158:28 + | +LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} + | ^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:158:48 + | +LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} + | ^^^^^^^^ + | +<<<<<<< HEAD + = help: try refactoring your code, extraction is often both easier to read and less nested +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= + = help: try refactoring your code to minimize nesting +>>>>>>> 88143ac29 (decided against reinventing the wheel) + +error: this block is too nested + --> $DIR/excessive_nesting.rs:160:14 + | +<<<<<<< HEAD +LL | &mut {{{{{{{{{{y}}}}}}}}}}; + | ^^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:156:17 + | +LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} + | ^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:156:28 + | +LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} + | ^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:158:28 + | +LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} + | ^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:158:48 + | +LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} + | ^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:160:14 + | +LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} + | ^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:160:35 + | +LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} + | ^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:162:23 + | +LL | let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:164:8 + | +LL | {{{{1;}}}}..{{{{{{3}}}}}}; + | ^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:164:20 + | +LL | {{{{1;}}}}..{{{{{{3}}}}}}; + | ^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:165:8 + | +LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; + | ^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:165:21 + | +LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:166:10 + | +LL | ..{{{{{{{5}}}}}}}; + | ^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:167:11 + | +LL | ..={{{{{3}}}}}; + | ^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:168:8 + | +LL | {{{{{1;}}}}}..; + | ^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:170:20 + | +LL | loop { break {{{{1}}}} }; + | ^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:171:13 + | +LL | loop {{{{{{}}}}}} + | ^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:173:14 + | +LL | match {{{{{{true}}}}}} { + | ^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:174:20 + | +LL | true => {{{{}}}}, + | ^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:175:21 + | +LL | false => {{{{}}}}, + | ^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:181:17 + | +LL | / { +LL | | println!("warning! :)"); +LL | | } + | |_________________^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:190:28 +======= +LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} + | ^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:160:35 + | +LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} + | ^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:162:23 + | +LL | let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:164:8 + | +LL | {{{{1;}}}}..{{{{{{3}}}}}}; + | ^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:164:20 + | +LL | {{{{1;}}}}..{{{{{{3}}}}}}; + | ^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:165:8 + | +LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; + | ^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:165:21 + | +LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:166:10 + | +LL | ..{{{{{{{5}}}}}}}; + | ^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:167:11 + | +LL | ..={{{{{3}}}}}; + | ^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:168:8 + | +LL | {{{{{1;}}}}}..; + | ^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:170:20 + | +LL | loop { break {{{{1}}}} }; + | ^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:171:13 + | +LL | loop {{{{{{}}}}}} + | ^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:173:14 + | +LL | match {{{{{{true}}}}}} { + | ^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:174:20 + | +LL | true => {{{{}}}}, + | ^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:175:21 + | +LL | false => {{{{}}}}, + | ^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:181:17 + | +LL | / { +LL | | println!("warning! :)"); +LL | | } + | |_________________^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:190:28 + | +LL | async fn c() -> u32 {{{{{{{0}}}}}}} + | ^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: this block is too nested +<<<<<<< HEAD +<<<<<<< HEAD:tests/ui-toml/excessive_nesting/excessive_nesting.above.stderr +<<<<<<< HEAD:tests/ui-toml/excessive_nesting/excessive_nesting.stderr +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/excessive_nesting.rs:184:28 +>>>>>>> e68dbc330 (add `excessive_nesting`) + | +LL | async fn c() -> u32 {{{{{{{0}}}}}}} + | ^^^^^^^^^ + | +<<<<<<< HEAD + = help: try refactoring your code to minimize nesting + +error: this block is too nested + --> $DIR/excessive_nesting.rs:196:8 +======= + --> $DIR/excessive_nesting.rs:195:8 +>>>>>>> 6afb3555d (remove revisions):tests/ui-toml/excessive_nesting/excessive_nesting.stderr +======= + --> $DIR/excessive_nesting.rs:196:8 +>>>>>>> 7ba904245 (make cargo test pass) + | +LL | {{{{b().await}}}}; + | ^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +error: aborting due to 37 previous errors +======= + = help: try refactoring your code, extraction is often both easier to read and less nested + +error: this block is too nested + --> $DIR/excessive_nesting.rs:190:7 +======= + --> $DIR/excessive_nesting.rs:191:7 +>>>>>>> 88143ac29 (decided against reinventing the wheel) +======= + --> $DIR/excessive_nesting.rs:193:7 +>>>>>>> 493a23e95 (check non-inline modules, ignore all macros) +======= + --> $DIR/excessive_nesting.rs:196:7 +>>>>>>> 378d77584 (work with lint attributes) +======= + --> $DIR/excessive_nesting.rs:198:8 +>>>>>>> 5da34559e (Check if from proc macro and better tests):tests/ui-toml/excessive_nesting/excessive_nesting.above.stderr + | +LL | {{{{b().await}}}}; + | ^^^^^^^^^^^ + | + = help: try refactoring your code to minimize nesting + +<<<<<<< HEAD:tests/ui-toml/excessive_nesting/excessive_nesting.stderr +<<<<<<< HEAD +error: aborting due to 40 previous errors +>>>>>>> e68dbc330 (add `excessive_nesting`) +======= +error: aborting due to 41 previous errors +>>>>>>> 493a23e95 (check non-inline modules, ignore all macros) +======= +error: aborting due to 37 previous errors +>>>>>>> 5da34559e (Check if from proc macro and better tests):tests/ui-toml/excessive_nesting/excessive_nesting.above.stderr + diff --git a/tests/ui-toml/excessive_nesting/set/clippy.toml b/tests/ui-toml/excessive_nesting/set/clippy.toml new file mode 100644 index 000000000000..9e62df75b002 --- /dev/null +++ b/tests/ui-toml/excessive_nesting/set/clippy.toml @@ -0,0 +1,5 @@ +<<<<<<< HEAD +excessive-nesting-threshold = 4 +======= +excessive-nesting-threshold = 3 +>>>>>>> e68dbc330 (add `excessive_nesting`) diff --git a/tests/ui-toml/expect_used/expect_used.rs b/tests/ui-toml/expect_used/expect_used.rs index 89f142a150d9..206788e19f02 100644 --- a/tests/ui-toml/expect_used/expect_used.rs +++ b/tests/ui-toml/expect_used/expect_used.rs @@ -1,5 +1,6 @@ -// compile-flags: --test +//@compile-flags: --test #![warn(clippy::expect_used)] +#![allow(clippy::unnecessary_literal_unwrap)] fn expect_option() { let opt = Some(0); diff --git a/tests/ui-toml/expect_used/expect_used.stderr b/tests/ui-toml/expect_used/expect_used.stderr index 1e9bb48c333c..9eef0e1bfaa1 100644 --- a/tests/ui-toml/expect_used/expect_used.stderr +++ b/tests/ui-toml/expect_used/expect_used.stderr @@ -1,5 +1,5 @@ error: used `expect()` on an `Option` value - --> $DIR/expect_used.rs:6:13 + --> $DIR/expect_used.rs:7:13 | LL | let _ = opt.expect(""); | ^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let _ = opt.expect(""); = note: `-D clippy::expect-used` implied by `-D warnings` error: used `expect()` on a `Result` value - --> $DIR/expect_used.rs:11:13 + --> $DIR/expect_used.rs:12:13 | LL | let _ = res.expect(""); | ^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs b/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs index d623ac7e0200..4882416c414a 100644 --- a/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs +++ b/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs @@ -1,5 +1,5 @@ #![warn(clippy::ifs_same_cond)] -#![allow(clippy::if_same_then_else, clippy::comparison_chain)] +#![allow(clippy::if_same_then_else, clippy::comparison_chain, clippy::needless_else)] fn main() {} diff --git a/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.rs b/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.rs index 2ebf28645e51..03fa719975b6 100644 --- a/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.rs +++ b/tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.rs @@ -1,3 +1,5 @@ +//@error-in-other-file: `invalid.version` is not a valid Rust version + #![allow(clippy::redundant_clone)] fn main() {} diff --git a/tests/ui-toml/lint_decimal_readability/test.rs b/tests/ui-toml/lint_decimal_readability/test.rs index 2498672d77fb..bd5110138c8c 100644 --- a/tests/ui-toml/lint_decimal_readability/test.rs +++ b/tests/ui-toml/lint_decimal_readability/test.rs @@ -1,5 +1,5 @@ #![allow(clippy::excessive_precision)] -#[deny(clippy::unreadable_literal)] +#![warn(clippy::unreadable_literal)] fn allow_inconsistent_digit_grouping() { #![allow(clippy::inconsistent_digit_grouping)] diff --git a/tests/ui-toml/lint_decimal_readability/test.stderr b/tests/ui-toml/lint_decimal_readability/test.stderr index be505bda4792..ac9d89d0cbee 100644 --- a/tests/ui-toml/lint_decimal_readability/test.stderr +++ b/tests/ui-toml/lint_decimal_readability/test.stderr @@ -6,5 +6,13 @@ LL | let _fail1 = 100_200_300.123456789; | = note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings` -error: aborting due to previous error +error: long literal lacking separators + --> $DIR/test.rs:22:18 + | +LL | let _fail2 = 100200300.300200100; + | ^^^^^^^^^^^^^^^^^^^ help: consider: `100_200_300.300_200_100` + | + = note: `-D clippy::unreadable-literal` implied by `-D warnings` + +error: aborting due to 2 previous errors diff --git a/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs b/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs index 21849a14fa95..da76bb20fd96 100644 --- a/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs +++ b/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs @@ -3,6 +3,7 @@ fn below_limit() { let slice: Option<&[u32]> = Some(&[1, 2, 3]); if let Some(slice) = slice { + //~^ ERROR: binding can be a slice pattern // This would usually not be linted but is included now due to the // index limit in the config file println!("{}", slice[7]); diff --git a/tests/ui-toml/min_ident_chars/auxiliary/extern_types.rs b/tests/ui-toml/min_ident_chars/auxiliary/extern_types.rs new file mode 100644 index 000000000000..06a144f2218c --- /dev/null +++ b/tests/ui-toml/min_ident_chars/auxiliary/extern_types.rs @@ -0,0 +1,3 @@ +#![allow(nonstandard_style, unused)] + +pub struct Aaa; diff --git a/tests/ui-toml/min_ident_chars/clippy.toml b/tests/ui-toml/min_ident_chars/clippy.toml new file mode 100644 index 000000000000..0114ca750143 --- /dev/null +++ b/tests/ui-toml/min_ident_chars/clippy.toml @@ -0,0 +1,2 @@ +allowed-idents-below-min-chars = ["Owo", "Uwu", "wha", "t_e", "lse", "_do", "_i_", "put", "her", "_e"] +min-ident-chars-threshold = 3 diff --git a/tests/ui-toml/min_ident_chars/min_ident_chars.rs b/tests/ui-toml/min_ident_chars/min_ident_chars.rs new file mode 100644 index 000000000000..aa83930272ea --- /dev/null +++ b/tests/ui-toml/min_ident_chars/min_ident_chars.rs @@ -0,0 +1,27 @@ +//@aux-build:extern_types.rs +#![allow(nonstandard_style, unused)] +#![warn(clippy::min_ident_chars)] + +extern crate extern_types; +use extern_types::Aaa; + +struct Owo { + Uwu: u128, + aaa: Aaa, +} + +fn main() { + let wha = 1; + let vvv = 1; + let uuu = 1; +<<<<<<< HEAD +<<<<<<< HEAD + let (mut a, mut b) = (1, 2); + for i in 0..1000 {} +======= +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + let (mut a, mut b) = (1, 2); + for i in 0..1000 {} +>>>>>>> 243943ff5 (make it work for locals as well) +} diff --git a/tests/ui-toml/min_ident_chars/min_ident_chars.stderr b/tests/ui-toml/min_ident_chars/min_ident_chars.stderr new file mode 100644 index 000000000000..754911300fad --- /dev/null +++ b/tests/ui-toml/min_ident_chars/min_ident_chars.stderr @@ -0,0 +1,72 @@ +<<<<<<< HEAD +<<<<<<< HEAD +error: this ident is too short (3 <= 3) +======= +error: this ident is too short (3 <= 3) +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +error: this ident is too short (3 <= 3) +>>>>>>> 243943ff5 (make it work for locals as well) + --> $DIR/min_ident_chars.rs:6:19 + | +LL | use extern_types::Aaa; + | ^^^ + | + = note: `-D clippy::min-ident-chars` implied by `-D warnings` + +<<<<<<< HEAD +<<<<<<< HEAD +error: this ident is too short (3 <= 3) +======= +error: this ident is too short (3 <= 3) +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +error: this ident is too short (3 <= 3) +>>>>>>> 243943ff5 (make it work for locals as well) + --> $DIR/min_ident_chars.rs:10:5 + | +LL | aaa: Aaa, + | ^^^ + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 243943ff5 (make it work for locals as well) +error: this ident is too short (3 <= 3) + --> $DIR/min_ident_chars.rs:15:9 + | +LL | let vvv = 1; + | ^^^ + +error: this ident is too short (3 <= 3) + --> $DIR/min_ident_chars.rs:16:9 + | +LL | let uuu = 1; + | ^^^ + +error: this ident is too short (1 <= 3) + --> $DIR/min_ident_chars.rs:17:14 + | +LL | let (mut a, mut b) = (1, 2); + | ^ + +error: this ident is too short (1 <= 3) + --> $DIR/min_ident_chars.rs:17:21 + | +LL | let (mut a, mut b) = (1, 2); + | ^ + +error: this ident is too short (1 <= 3) + --> $DIR/min_ident_chars.rs:18:9 + | +LL | for i in 0..1000 {} + | ^ + +error: aborting due to 7 previous errors +<<<<<<< HEAD +======= +error: aborting due to 2 previous errors +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +>>>>>>> 243943ff5 (make it work for locals as well) + diff --git a/tests/ui-toml/min_rust_version/min_rust_version.rs b/tests/ui-toml/min_rust_version/min_rust_version.rs index 1e3ec123a3c8..e1dc3f4389c0 100644 --- a/tests/ui-toml/min_rust_version/min_rust_version.rs +++ b/tests/ui-toml/min_rust_version/min_rust_version.rs @@ -41,7 +41,7 @@ fn match_like_matches() { fn match_same_arms() { match (1, 2, 3) { (1, .., 3) => 42, - (.., 3) => 42, //~ ERROR match arms have same body + (.., 3) => 42, _ => 0, }; } @@ -49,7 +49,7 @@ fn match_same_arms() { fn match_same_arms2() { let _ = match Some(42) { Some(_) => 24, - None => 24, //~ ERROR match arms have same body + None => 24, }; } diff --git a/tests/ui-toml/module_inception/clippy.toml b/tests/ui-toml/module_inception/clippy.toml new file mode 100644 index 000000000000..787620d865cc --- /dev/null +++ b/tests/ui-toml/module_inception/clippy.toml @@ -0,0 +1 @@ +allow-private-module-inception = true diff --git a/tests/ui-toml/module_inception/module_inception.rs b/tests/ui-toml/module_inception/module_inception.rs new file mode 100644 index 000000000000..cd495c884a43 --- /dev/null +++ b/tests/ui-toml/module_inception/module_inception.rs @@ -0,0 +1,34 @@ +#![warn(clippy::module_inception)] + +// Lint +pub mod foo2 { + pub mod bar2 { + pub mod bar2 { + pub mod foo2 {} + } + pub mod foo2 {} + } + pub mod foo2 { + pub mod bar2 {} + } +} + +// Don't lint +mod foo { + pub mod bar { + pub mod foo { + pub mod bar {} + } + } + pub mod foo { + pub mod bar {} + } +} + +// No warning. See . +pub mod bar { + #[allow(clippy::module_inception)] + pub mod bar {} +} + +fn main() {} diff --git a/tests/ui-toml/module_inception/module_inception.stderr b/tests/ui-toml/module_inception/module_inception.stderr new file mode 100644 index 000000000000..a5a09c322e13 --- /dev/null +++ b/tests/ui-toml/module_inception/module_inception.stderr @@ -0,0 +1,20 @@ +error: module has the same name as its containing module + --> $DIR/module_inception.rs:6:9 + | +LL | / pub mod bar2 { +LL | | pub mod foo2 {} +LL | | } + | |_________^ + | + = note: `-D clippy::module-inception` implied by `-D warnings` + +error: module has the same name as its containing module + --> $DIR/module_inception.rs:11:5 + | +LL | / pub mod foo2 { +LL | | pub mod bar2 {} +LL | | } + | |_____^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui-toml/mut_key/mut_key.rs b/tests/ui-toml/mut_key/mut_key.rs index 667c51cb4a3f..095e0d15448a 100644 --- a/tests/ui-toml/mut_key/mut_key.rs +++ b/tests/ui-toml/mut_key/mut_key.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name mut_key +//@compile-flags: --crate-name mut_key #![warn(clippy::mutable_key_type)] diff --git a/tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs b/tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs index 6452189a4615..5b9fecef97bf 100644 --- a/tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs +++ b/tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs @@ -1,8 +1,11 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +<<<<<<< HEAD +======= +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] +>>>>>>> e4f5d83fa (Fixed formatting.) extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed index 01d135764dff..8fd51147801b 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed @@ -1,5 +1,9 @@ -// aux-build:proc_macro_derive.rs -// run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) +//@run-rustfix #![warn(clippy::nonstandard_macro_braces)] diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs index 72883e8270c3..fd7f65d8e3e8 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs @@ -1,5 +1,9 @@ -// aux-build:proc_macro_derive.rs -// run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) +//@run-rustfix #![warn(clippy::nonstandard_macro_braces)] diff --git a/tests/ui-toml/print_macro/print_macro.rs b/tests/ui-toml/print_macro/print_macro.rs index 5aefb6a6b4d4..3a8b30cca36a 100644 --- a/tests/ui-toml/print_macro/print_macro.rs +++ b/tests/ui-toml/print_macro/print_macro.rs @@ -1,4 +1,4 @@ -// compile-flags: --test +//@compile-flags: --test #![warn(clippy::print_stdout)] #![warn(clippy::print_stderr)] diff --git a/tests/ui-toml/semicolon_block/both.fixed b/tests/ui-toml/semicolon_block/both.fixed new file mode 100644 index 000000000000..7a3bae1dc41b --- /dev/null +++ b/tests/ui-toml/semicolon_block/both.fixed @@ -0,0 +1,94 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= +// run-rustfix +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= +//@run-rustfix +>>>>>>> e3ee10d42 (use `//@` for commands in tests) +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_inside_block)] +#![warn(clippy::semicolon_outside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()) }; + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/tests/ui-toml/semicolon_block/both.rs b/tests/ui-toml/semicolon_block/both.rs new file mode 100644 index 000000000000..1b3d476864b1 --- /dev/null +++ b/tests/ui-toml/semicolon_block/both.rs @@ -0,0 +1,94 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= +// run-rustfix +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= +//@run-rustfix +>>>>>>> e3ee10d42 (use `//@` for commands in tests) +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_inside_block)] +#![warn(clippy::semicolon_outside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); } + unsafe { unit_fn_block(); } + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block() + }; + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()); } + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/tests/ui-toml/semicolon_block/both.stderr b/tests/ui-toml/semicolon_block/both.stderr new file mode 100644 index 000000000000..2f58842eab01 --- /dev/null +++ b/tests/ui-toml/semicolon_block/both.stderr @@ -0,0 +1,55 @@ +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/both.rs:43:5 + | +LL | { unit_fn_block(); } + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::semicolon-outside-block` implied by `-D warnings` +help: put the `;` here + | +LL - { unit_fn_block(); } +LL + { unit_fn_block() }; + | + +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/both.rs:44:5 + | +LL | unsafe { unit_fn_block(); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: put the `;` here + | +LL - unsafe { unit_fn_block(); } +LL + unsafe { unit_fn_block() }; + | + +error: consider moving the `;` inside the block for consistent formatting + --> $DIR/both.rs:49:5 + | +LL | / { +LL | | unit_fn_block(); +LL | | unit_fn_block() +LL | | }; + | |______^ + | + = note: `-D clippy::semicolon-inside-block` implied by `-D warnings` +help: put the `;` here + | +LL ~ unit_fn_block(); +LL ~ } + | + +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/both.rs:63:5 + | +LL | { m!(()); } + | ^^^^^^^^^^^ + | +help: put the `;` here + | +LL - { m!(()); } +LL + { m!(()) }; + | + +error: aborting due to 4 previous errors + diff --git a/tests/ui-toml/semicolon_block/clippy.toml b/tests/ui-toml/semicolon_block/clippy.toml new file mode 100644 index 000000000000..32ec56d069da --- /dev/null +++ b/tests/ui-toml/semicolon_block/clippy.toml @@ -0,0 +1,12 @@ +<<<<<<< HEAD +<<<<<<< HEAD +semicolon-inside-block-ignore-singleline = true +semicolon-outside-block-ignore-multiline = true +======= +semicolon-inside-block-if-multiline = true +semicolon-outside-block-if-singleline = true +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= +semicolon-inside-block-ignore-singleline = true +semicolon-outside-block-ignore-multiline = true +>>>>>>> aa6c27a74 (change names to not be implicitly negative) diff --git a/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed b/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed new file mode 100644 index 000000000000..a45d20050706 --- /dev/null +++ b/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed @@ -0,0 +1,93 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= +// run-rustfix +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= +//@run-rustfix +>>>>>>> e3ee10d42 (use `//@` for commands in tests) +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_inside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); } + unsafe { unit_fn_block(); } + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()); } + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/tests/ui-toml/semicolon_block/semicolon_inside_block.rs b/tests/ui-toml/semicolon_block/semicolon_inside_block.rs new file mode 100644 index 000000000000..392d5eadda74 --- /dev/null +++ b/tests/ui-toml/semicolon_block/semicolon_inside_block.rs @@ -0,0 +1,93 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= +// run-rustfix +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= +//@run-rustfix +>>>>>>> e3ee10d42 (use `//@` for commands in tests) +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_inside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); } + unsafe { unit_fn_block(); } + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block() + }; + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()); } + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr b/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr new file mode 100644 index 000000000000..2569dc4b4e45 --- /dev/null +++ b/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr @@ -0,0 +1,18 @@ +error: consider moving the `;` inside the block for consistent formatting + --> $DIR/semicolon_inside_block.rs:48:5 + | +LL | / { +LL | | unit_fn_block(); +LL | | unit_fn_block() +LL | | }; + | |______^ + | + = note: `-D clippy::semicolon-inside-block` implied by `-D warnings` +help: put the `;` here + | +LL ~ unit_fn_block(); +LL ~ } + | + +error: aborting due to previous error + diff --git a/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed b/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed new file mode 100644 index 000000000000..265c78fd8cae --- /dev/null +++ b/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed @@ -0,0 +1,93 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= +// run-rustfix +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= +//@run-rustfix +>>>>>>> e3ee10d42 (use `//@` for commands in tests) +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_outside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block() + }; + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()) }; + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/tests/ui-toml/semicolon_block/semicolon_outside_block.rs b/tests/ui-toml/semicolon_block/semicolon_outside_block.rs new file mode 100644 index 000000000000..a1ecef85e768 --- /dev/null +++ b/tests/ui-toml/semicolon_block/semicolon_outside_block.rs @@ -0,0 +1,93 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= +// run-rustfix +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= +//@run-rustfix +>>>>>>> e3ee10d42 (use `//@` for commands in tests) +#![allow( + unused, + clippy::unused_unit, + clippy::unnecessary_operation, + clippy::no_effect, + clippy::single_element_loop +)] +#![warn(clippy::semicolon_outside_block)] + +macro_rules! m { + (()) => { + () + }; + (0) => {{ + 0 + };}; + (1) => {{ + 1; + }}; + (2) => {{ + 2; + }}; +} + +fn unit_fn_block() { + () +} + +#[rustfmt::skip] +fn main() { + { unit_fn_block() } + unsafe { unit_fn_block() } + + { + unit_fn_block() + } + + { unit_fn_block() }; + unsafe { unit_fn_block() }; + + { unit_fn_block(); } + unsafe { unit_fn_block(); } + + { unit_fn_block(); }; + unsafe { unit_fn_block(); }; + + { + unit_fn_block(); + unit_fn_block() + }; + { + unit_fn_block(); + unit_fn_block(); + } + { + unit_fn_block(); + unit_fn_block(); + }; + + { m!(()) }; + { m!(()); } + { m!(()); }; + m!(0); + m!(1); + m!(2); + + for _ in [()] { + unit_fn_block(); + } + for _ in [()] { + unit_fn_block() + } + + let _d = || { + unit_fn_block(); + }; + let _d = || { + unit_fn_block() + }; + + { unit_fn_block(); }; + + unit_fn_block() +} diff --git a/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr b/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr new file mode 100644 index 000000000000..6dd3577dd09f --- /dev/null +++ b/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr @@ -0,0 +1,39 @@ +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/semicolon_outside_block.rs:42:5 + | +LL | { unit_fn_block(); } + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::semicolon-outside-block` implied by `-D warnings` +help: put the `;` here + | +LL - { unit_fn_block(); } +LL + { unit_fn_block() }; + | + +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/semicolon_outside_block.rs:43:5 + | +LL | unsafe { unit_fn_block(); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: put the `;` here + | +LL - unsafe { unit_fn_block(); } +LL + unsafe { unit_fn_block() }; + | + +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/semicolon_outside_block.rs:62:5 + | +LL | { m!(()); } + | ^^^^^^^^^^^ + | +help: put the `;` here + | +LL - { m!(()); } +LL + { m!(()) }; + | + +error: aborting due to 3 previous errors + diff --git a/tests/ui-toml/suppress_lint_in_const/test.rs b/tests/ui-toml/suppress_lint_in_const/test.rs index 5a2df9f6c5d9..17c1b03d88c6 100644 --- a/tests/ui-toml/suppress_lint_in_const/test.rs +++ b/tests/ui-toml/suppress_lint_in_const/test.rs @@ -3,11 +3,17 @@ // We also check the out_of_bounds_indexing lint here, because it lints similar things and // we want to avoid false positives. #![warn(clippy::out_of_bounds_indexing)] -#![allow(unconditional_panic, clippy::no_effect, clippy::unnecessary_operation)] +#![allow( + unconditional_panic, + clippy::no_effect, + clippy::unnecessary_operation, + clippy::useless_vec +)] const ARR: [i32; 2] = [1, 2]; const REF: &i32 = &ARR[idx()]; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true. const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts. +//~^ ERROR: failed const fn idx() -> usize { 1 @@ -29,6 +35,8 @@ fn main() { x[const { idx4() }]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays. const { &ARR[idx()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true. const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true. + // + //~^^ ERROR: failed let y = &x; y[0]; // Ok, referencing shouldn't affect this lint. See the issue 6021 diff --git a/tests/ui-toml/suppress_lint_in_const/test.stderr b/tests/ui-toml/suppress_lint_in_const/test.stderr index bc178b7e1319..8aecfd6b7c08 100644 --- a/tests/ui-toml/suppress_lint_in_const/test.stderr +++ b/tests/ui-toml/suppress_lint_in_const/test.stderr @@ -1,17 +1,41 @@ error[E0080]: evaluation of `main::{constant#3}` failed - --> $DIR/test.rs:31:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/test.rs:37:14 +======= + --> $DIR/test.rs:36:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/test.rs:37:14 +>>>>>>> 5bd97ac17 (Update tests) | LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true. | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 note: erroneous constant used - --> $DIR/test.rs:31:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/test.rs:37:5 +======= + --> $DIR/test.rs:36:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/test.rs:37:5 +>>>>>>> 5bd97ac17 (Update tests) | LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true. | ^^^^^^^^^^^^^^^^^^^^^^ error: indexing may panic - --> $DIR/test.rs:22:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/test.rs:28:5 +======= + --> $DIR/test.rs:27:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/test.rs:28:5 +>>>>>>> 5bd97ac17 (Update tests) | LL | x[index]; | ^^^^^^^^ @@ -20,7 +44,15 @@ LL | x[index]; = note: `-D clippy::indexing-slicing` implied by `-D warnings` error: indexing may panic - --> $DIR/test.rs:38:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/test.rs:46:5 +======= + --> $DIR/test.rs:43:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/test.rs:46:5 +>>>>>>> 5bd97ac17 (Update tests) | LL | v[0]; | ^^^^ @@ -28,7 +60,15 @@ LL | v[0]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/test.rs:39:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/test.rs:47:5 +======= + --> $DIR/test.rs:44:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/test.rs:47:5 +>>>>>>> 5bd97ac17 (Update tests) | LL | v[10]; | ^^^^^ @@ -36,7 +76,15 @@ LL | v[10]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/test.rs:40:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/test.rs:48:5 +======= + --> $DIR/test.rs:45:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/test.rs:48:5 +>>>>>>> 5bd97ac17 (Update tests) | LL | v[1 << 3]; | ^^^^^^^^^ @@ -44,7 +92,15 @@ LL | v[1 << 3]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/test.rs:46:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/test.rs:54:5 +======= + --> $DIR/test.rs:51:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/test.rs:54:5 +>>>>>>> 5bd97ac17 (Update tests) | LL | v[N]; | ^^^^ @@ -52,7 +108,15 @@ LL | v[N]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/test.rs:47:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/test.rs:55:5 +======= + --> $DIR/test.rs:52:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/test.rs:55:5 +>>>>>>> 5bd97ac17 (Update tests) | LL | v[M]; | ^^^^ @@ -60,7 +124,7 @@ LL | v[M]; = help: consider using `.get(n)` or `.get_mut(n)` instead error[E0080]: evaluation of constant value failed - --> $DIR/test.rs:10:24 + --> $DIR/test.rs:15:24 | LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts. | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs index 2f3160c83383..eb4a5ca468f0 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs @@ -1,6 +1,16 @@ -// compile-flags: --crate-name conf_disallowed_methods - +//@compile-flags: --crate-name conf_disallowed_methods + +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::needless_raw_strings)] +======= +#![allow(clippy::needless_raw_string)] +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= +#![allow(clippy::needless_raw_strings)] +>>>>>>> 8cb6c8699 (change category and refactor) #![warn(clippy::disallowed_methods)] +#![allow(clippy::useless_vec)] extern crate futures; extern crate regex; diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr index 148d1cae51f1..c2bb2becc088 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr @@ -1,5 +1,13 @@ error: use of a disallowed method `regex::Regex::new` - --> $DIR/conf_disallowed_methods.rs:33:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:35:14 +======= + --> $DIR/conf_disallowed_methods.rs:34:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:35:14 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let re = Regex::new(r"ab.*c").unwrap(); | ^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +15,15 @@ LL | let re = Regex::new(r"ab.*c").unwrap(); = note: `-D clippy::disallowed-methods` implied by `-D warnings` error: use of a disallowed method `regex::Regex::is_match` - --> $DIR/conf_disallowed_methods.rs:34:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:36:5 +======= + --> $DIR/conf_disallowed_methods.rs:35:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:36:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | re.is_match("abc"); | ^^^^^^^^^^^^^^^^^^ @@ -15,73 +31,169 @@ LL | re.is_match("abc"); = note: no matching allowed (from clippy.toml) error: use of a disallowed method `std::iter::Iterator::sum` - --> $DIR/conf_disallowed_methods.rs:37:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:39:5 +======= + --> $DIR/conf_disallowed_methods.rs:38:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:39:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | a.iter().sum::(); | ^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed method `slice::sort_unstable` - --> $DIR/conf_disallowed_methods.rs:39:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:41:5 +======= + --> $DIR/conf_disallowed_methods.rs:40:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:41:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | a.sort_unstable(); | ^^^^^^^^^^^^^^^^^ error: use of a disallowed method `f32::clamp` - --> $DIR/conf_disallowed_methods.rs:41:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:43:13 +======= + --> $DIR/conf_disallowed_methods.rs:42:13 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:43:13 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let _ = 2.0f32.clamp(3.0f32, 4.0f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed method `regex::Regex::new` - --> $DIR/conf_disallowed_methods.rs:44:61 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:46:61 +======= + --> $DIR/conf_disallowed_methods.rs:45:61 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:46:61 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let indirect: fn(&str) -> Result = Regex::new; | ^^^^^^^^^^ error: use of a disallowed method `f32::clamp` - --> $DIR/conf_disallowed_methods.rs:47:28 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:49:28 +======= + --> $DIR/conf_disallowed_methods.rs:48:28 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:49:28 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let in_call = Box::new(f32::clamp); | ^^^^^^^^^^ error: use of a disallowed method `regex::Regex::new` - --> $DIR/conf_disallowed_methods.rs:48:53 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:50:53 +======= + --> $DIR/conf_disallowed_methods.rs:49:53 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:50:53 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let in_method_call = ["^", "$"].into_iter().map(Regex::new); | ^^^^^^^^^^ error: use of a disallowed method `futures::stream::select_all` - --> $DIR/conf_disallowed_methods.rs:51:31 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:53:31 +======= + --> $DIR/conf_disallowed_methods.rs:52:31 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:53:31 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let same_name_as_module = select_all(vec![empty::<()>()]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::local_fn` - --> $DIR/conf_disallowed_methods.rs:53:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:55:5 +======= + --> $DIR/conf_disallowed_methods.rs:54:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:55:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | local_fn(); | ^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::local_mod::f` - --> $DIR/conf_disallowed_methods.rs:54:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:56:5 +======= + --> $DIR/conf_disallowed_methods.rs:55:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:56:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | local_mod::f(); | ^^^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Struct::method` - --> $DIR/conf_disallowed_methods.rs:56:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:58:5 +======= + --> $DIR/conf_disallowed_methods.rs:57:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:58:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | s.method(); | ^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Trait::provided_method` - --> $DIR/conf_disallowed_methods.rs:57:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:59:5 +======= + --> $DIR/conf_disallowed_methods.rs:58:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:59:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | s.provided_method(); | ^^^^^^^^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Trait::implemented_method` - --> $DIR/conf_disallowed_methods.rs:58:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/conf_disallowed_methods.rs:60:5 +======= + --> $DIR/conf_disallowed_methods.rs:59:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/conf_disallowed_methods.rs:60:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | s.implemented_method(); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/toml_trivially_copy/test.rs b/tests/ui-toml/toml_trivially_copy/test.rs index fb0e226f3aa4..78784bfff0fd 100644 --- a/tests/ui-toml/toml_trivially_copy/test.rs +++ b/tests/ui-toml/toml_trivially_copy/test.rs @@ -1,7 +1,8 @@ -// normalize-stderr-test "\(\d+ byte\)" -> "(N byte)" -// normalize-stderr-test "\(limit: \d+ byte\)" -> "(limit: N byte)" +//@normalize-stderr-test: "\(\d+ byte\)" -> "(N byte)" +//@normalize-stderr-test: "\(limit: \d+ byte\)" -> "(limit: N byte)" -#![deny(clippy::trivially_copy_pass_by_ref)] +#![warn(clippy::trivially_copy_pass_by_ref)] +#![allow(clippy::needless_pass_by_ref_mut)] #[derive(Copy, Clone)] struct Foo(u8); diff --git a/tests/ui-toml/toml_trivially_copy/test.stderr b/tests/ui-toml/toml_trivially_copy/test.stderr index b3ef5928e8ea..db5d6805362d 100644 --- a/tests/ui-toml/toml_trivially_copy/test.stderr +++ b/tests/ui-toml/toml_trivially_copy/test.stderr @@ -1,17 +1,13 @@ error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/test.rs:14:11 + --> $DIR/test.rs:15:11 | LL | fn bad(x: &u16, y: &Foo) {} | ^^^^ help: consider passing by value instead: `u16` | -note: the lint level is defined here - --> $DIR/test.rs:4:9 - | -LL | #![deny(clippy::trivially_copy_pass_by_ref)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::trivially-copy-pass-by-ref` implied by `-D warnings` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/test.rs:14:20 + --> $DIR/test.rs:15:20 | LL | fn bad(x: &u16, y: &Foo) {} | ^^^^ help: consider passing by value instead: `Foo` diff --git a/tests/ui-toml/toml_unknown_key/clippy.toml b/tests/ui-toml/toml_unknown_key/clippy.toml index 554b87cc50be..b77b4580051e 100644 --- a/tests/ui-toml/toml_unknown_key/clippy.toml +++ b/tests/ui-toml/toml_unknown_key/clippy.toml @@ -1,6 +1,8 @@ # that one is an error foobar = 42 +# so is this one +barfoo = 53 -# that one is white-listed +# that one is ignored [third-party] clippy-feature = "nightly" diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs b/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs index f328e4d9d04c..3bb97e48d3db 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs @@ -1 +1,7 @@ +<<<<<<< HEAD +//@error-in-other-file: unknown field `foobar`, expected one of +======= +//@error-pattern: unknown field `foobar`, expected one of +>>>>>>> e4f5d83fa (Fixed formatting.) + fn main() {} diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 8447c31722dd..07f298d7c45b 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -1,9 +1,40 @@ -error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of +error: error reading Clippy's configuration file: unknown field `foobar`, expected one of +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) + accept-comment-above-attributes + accept-comment-above-statement +======= +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + accept-comment-above-statement +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) allow-dbg-in-tests allow-expect-in-tests allow-mixed-uninlined-format-args +<<<<<<< HEAD +<<<<<<< HEAD + allow-one-hash-in-raw-strings +======= + allow-one-hash-in-raw-string +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= + allow-one-hash-in-raw-strings +>>>>>>> 8cb6c8699 (change category and refactor) allow-print-in-tests + allow-private-module-inception allow-unwrap-in-tests +<<<<<<< HEAD +<<<<<<< HEAD + allowed-idents-below-min-chars +======= + allowed-idents +>>>>>>> 52cfc997a (Add lint `single_letter_idents`) +======= + allowed-idents-below-min-chars +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) allowed-scripts arithmetic-side-effects-allowed arithmetic-side-effects-allowed-binary @@ -24,6 +55,7 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie enforced-import-renames enum-variant-name-threshold enum-variant-size-threshold + excessive-nesting-threshold future-size-threshold ignore-interior-mutability large-error-threshold @@ -34,10 +66,24 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie max-struct-bools max-suggested-slice-pattern-length max-trait-bounds + min-ident-chars-threshold missing-docs-in-crate-items msrv pass-by-value-size-limit +<<<<<<< HEAD +<<<<<<< HEAD + semicolon-inside-block-ignore-singleline + semicolon-outside-block-ignore-multiline +======= + semicolon-inside-block-if-multiline + semicolon-outside-block-if-singleline +>>>>>>> a3aeec4f7 (config instead of new lint and don't panic) +======= + semicolon-inside-block-ignore-singleline + semicolon-outside-block-ignore-multiline +>>>>>>> aa6c27a74 (change names to not be implicitly negative) single-char-binding-names-threshold + stack-size-threshold standard-macro-braces suppress-restriction-lint-in-const third-party @@ -46,12 +92,153 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie too-many-lines-threshold trivial-copy-size-limit type-complexity-threshold + unnecessary-box-size unreadable-literal-lint-fractions upper-case-acronyms-aggressive vec-box-size-threshold verbose-bit-mask-threshold warn-on-all-wildcard-imports - at line 5 column 1 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/$DIR/clippy.toml:2:1 +======= + --> $DIR/clippy.toml:2:1 +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + --> $DIR/$DIR/clippy.toml:2:1 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | foobar = 42 + | ^^^^^^ -error: aborting due to previous error +error: error reading Clippy's configuration file: unknown field `barfoo`, expected one of +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) + accept-comment-above-attributes + accept-comment-above-statement + allow-dbg-in-tests + allow-expect-in-tests + allow-mixed-uninlined-format-args +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 8cb6c8699 (change category and refactor) + allow-one-hash-in-raw-strings + allow-print-in-tests + allow-private-module-inception + allow-unwrap-in-tests + allowed-idents-below-min-chars +======= +======= + accept-comment-above-statement +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) + allow-dbg-in-tests + allow-expect-in-tests + allow-mixed-uninlined-format-args +======= + allow-one-hash-in-raw-string +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) + allow-print-in-tests + allow-private-module-inception + allow-unwrap-in-tests +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + allowed-idents +>>>>>>> 52cfc997a (Add lint `single_letter_idents`) +======= + allowed-idents-below-min-chars +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) + allowed-scripts + arithmetic-side-effects-allowed + arithmetic-side-effects-allowed-binary + arithmetic-side-effects-allowed-unary + array-size-threshold + avoid-breaking-exported-api + await-holding-invalid-types + blacklisted-names + cargo-ignore-publish + cognitive-complexity-threshold + cyclomatic-complexity-threshold + disallowed-macros + disallowed-methods + disallowed-names + disallowed-types + doc-valid-idents + enable-raw-pointer-heuristic-for-send + enforced-import-renames + enum-variant-name-threshold + enum-variant-size-threshold +<<<<<<< HEAD +<<<<<<< HEAD + excessive-nesting-threshold +======= +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + excessive-nesting-threshold +>>>>>>> 5da34559e (Check if from proc macro and better tests) + future-size-threshold + ignore-interior-mutability + large-error-threshold + literal-representation-threshold + matches-for-let-else + max-fn-params-bools + max-include-file-size + max-struct-bools + max-suggested-slice-pattern-length + max-trait-bounds +<<<<<<< HEAD +<<<<<<< HEAD + min-ident-chars-threshold +======= +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + min-ident-chars-threshold +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) + missing-docs-in-crate-items + msrv + pass-by-value-size-limit + semicolon-inside-block-ignore-singleline + semicolon-outside-block-ignore-multiline + single-char-binding-names-threshold +<<<<<<< HEAD +<<<<<<< HEAD + stack-size-threshold +======= +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + stack-size-threshold +>>>>>>> c8c7a3c79 (fix rebase weirdness) + standard-macro-braces + suppress-restriction-lint-in-const + third-party + too-large-for-stack + too-many-arguments-threshold + too-many-lines-threshold + trivial-copy-size-limit + type-complexity-threshold + unnecessary-box-size + unreadable-literal-lint-fractions + upper-case-acronyms-aggressive + vec-box-size-threshold + verbose-bit-mask-threshold + warn-on-all-wildcard-imports +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/$DIR/clippy.toml:4:1 +======= + --> $DIR/clippy.toml:4:1 +>>>>>>> 6f13a3749 (Add spans to `clippy.toml` error messages) +======= + --> $DIR/$DIR/clippy.toml:4:1 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | barfoo = 53 + | ^^^^^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui-toml/undocumented_unsafe_blocks/auxiliary/proc_macro_unsafe.rs b/tests/ui-toml/undocumented_unsafe_blocks/auxiliary/proc_macro_unsafe.rs new file mode 100644 index 000000000000..71ab3867d44b --- /dev/null +++ b/tests/ui-toml/undocumented_unsafe_blocks/auxiliary/proc_macro_unsafe.rs @@ -0,0 +1,24 @@ +<<<<<<< HEAD +<<<<<<< HEAD +======= +//@compile-flags: --emit=link +//@no-prefer-dynamic + +#![crate_type = "proc-macro"] + +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= +>>>>>>> 5bd97ac17 (Update tests) +extern crate proc_macro; + +use proc_macro::{Delimiter, Group, Ident, TokenStream, TokenTree}; + +#[proc_macro] +pub fn unsafe_block(input: TokenStream) -> TokenStream { + let span = input.into_iter().next().unwrap().span(); + TokenStream::from_iter([TokenTree::Ident(Ident::new("unsafe", span)), { + let mut group = Group::new(Delimiter::Brace, TokenStream::new()); + group.set_span(span); + TokenTree::Group(group) + }]) +} diff --git a/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml b/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml new file mode 100644 index 000000000000..656075a59dda --- /dev/null +++ b/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml @@ -0,0 +1,9 @@ +accept-comment-above-statement = true +<<<<<<< HEAD +<<<<<<< HEAD +accept-comment-above-attributes = true +======= +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= +accept-comment-above-attributes = true +>>>>>>> cc2e49f69 (allow safety comment above attributes) diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs new file mode 100644 index 000000000000..82b8cbd7756f --- /dev/null +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs @@ -0,0 +1,1130 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macro_unsafe.rs:proc-macro + +#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)] +#![allow(deref_nullptr, clippy::let_unit_value, clippy::missing_safety_doc)] +#![feature(lint_reasons)] + +extern crate proc_macro_unsafe; + +// Valid comments + +fn nested_local() { + let _ = { + let _ = { + // SAFETY: + let _ = unsafe {}; + }; + }; +} + +fn deep_nest() { + let _ = { + let _ = { + // SAFETY: + let _ = unsafe {}; + + // Safety: + unsafe {}; + + let _ = { + let _ = { + let _ = { + let _ = { + let _ = { + // Safety: + let _ = unsafe {}; + + // SAFETY: + unsafe {}; + }; + }; + }; + + // Safety: + unsafe {}; + }; + }; + }; + + // Safety: + unsafe {}; + }; + + // SAFETY: + unsafe {}; +} + +fn local_tuple_expression() { + // Safety: + let _ = (42, unsafe {}); +} + +fn line_comment() { + // Safety: + unsafe {} +} + +fn line_comment_newlines() { + // SAFETY: + + unsafe {} +} + +fn line_comment_empty() { + // Safety: + // + // + // + unsafe {} +} + +fn line_comment_with_extras() { + // This is a description + // Safety: + unsafe {} +} + +fn block_comment() { + /* Safety: */ + unsafe {} +} + +fn block_comment_newlines() { + /* SAFETY: */ + + unsafe {} +} + +fn block_comment_with_extras() { + /* This is a description + * SAFETY: + */ + unsafe {} +} + +fn block_comment_terminator_same_line() { + /* This is a description + * Safety: */ + unsafe {} +} + +fn buried_safety() { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor + // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation + // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in + // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint + // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + // laborum. Safety: + // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi + // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio + // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl + // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus. + unsafe {} +} + +fn safety_with_prepended_text() { + // This is a test. safety: + unsafe {} +} + +fn local_line_comment() { + // Safety: + let _ = unsafe {}; +} + +fn local_block_comment() { + /* SAFETY: */ + let _ = unsafe {}; +} + +fn comment_array() { + // Safety: + let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; +} + +fn comment_tuple() { + // sAFETY: + let _ = (42, unsafe {}, "test", unsafe {}); +} + +fn comment_unary() { + // SAFETY: + let _ = *unsafe { &42 }; +} + +#[allow(clippy::match_single_binding)] +fn comment_match() { + // SAFETY: + let _ = match unsafe {} { + _ => {}, + }; +} + +fn comment_addr_of() { + // Safety: + let _ = &unsafe {}; +} + +fn comment_repeat() { + // Safety: + let _ = [unsafe {}; 5]; +} + +fn comment_macro_call() { + macro_rules! t { + ($b:expr) => { + $b + }; + } + + t!( + // SAFETY: + unsafe {} + ); +} + +fn comment_macro_def() { + macro_rules! t { + () => { + // Safety: + unsafe {} + }; + } + + t!(); +} + +fn non_ascii_comment() { + // ॐ᧻໒ SaFeTy: ௵∰ + unsafe {}; +} + +fn local_commented_block() { + let _ = + // safety: + unsafe {}; +} + +fn local_nest() { + // safety: + let _ = [(42, unsafe {}, unsafe {}), (52, unsafe {}, unsafe {})]; +} + +fn in_fn_call(x: *const u32) { + fn f(x: u32) {} + + // Safety: reason + f(unsafe { *x }); +} + +fn multi_in_fn_call(x: *const u32) { + fn f(x: u32, y: u32) {} + + // Safety: reason + f(unsafe { *x }, unsafe { *x }); +} + +fn in_multiline_fn_call(x: *const u32) { + fn f(x: u32, y: u32) {} + + f( + // Safety: reason + unsafe { *x }, + 0, + ); +} + +fn in_macro_call(x: *const u32) { + // Safety: reason + println!("{}", unsafe { *x }); +} + +fn in_multiline_macro_call(x: *const u32) { + println!( + "{}", + // Safety: reason + unsafe { *x }, + ); +} + +fn from_proc_macro() { + proc_macro_unsafe::unsafe_block!(token); +} + +fn in_closure(x: *const u32) { + // Safety: reason + let _ = || unsafe { *x }; +} + +// Invalid comments + +#[rustfmt::skip] +fn inline_block_comment() { + /* Safety: */ unsafe {} +} + +fn no_comment() { + unsafe {} +} + +fn no_comment_array() { + let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; +} + +fn no_comment_tuple() { + let _ = (42, unsafe {}, "test", unsafe {}); +} + +fn no_comment_unary() { + let _ = *unsafe { &42 }; +} + +#[allow(clippy::match_single_binding)] +fn no_comment_match() { + let _ = match unsafe {} { + _ => {}, + }; +} + +fn no_comment_addr_of() { + let _ = &unsafe {}; +} + +fn no_comment_repeat() { + let _ = [unsafe {}; 5]; +} + +fn local_no_comment() { + let _ = unsafe {}; +} + +fn no_comment_macro_call() { + macro_rules! t { + ($b:expr) => { + $b + }; + } + + t!(unsafe {}); +} + +fn no_comment_macro_def() { + macro_rules! t { + () => { + unsafe {} + }; + } + + t!(); +} + +fn trailing_comment() { + unsafe {} // SAFETY: +} + +fn internal_comment() { + unsafe { + // SAFETY: + } +} + +fn interference() { + // SAFETY + + let _ = 42; + + unsafe {}; +} + +pub fn print_binary_tree() { + println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); +} + +mod unsafe_impl_smoke_test { + unsafe trait A {} + + // error: no safety comment + unsafe impl A for () {} + + // Safety: ok + unsafe impl A for (i32) {} + + mod sub_mod { + // error: + unsafe impl B for (u32) {} + unsafe trait B {} + } + + #[rustfmt::skip] + mod sub_mod2 { + // + // SAFETY: ok + // + + unsafe impl B for (u32) {} + unsafe trait B {} + } +} + +mod unsafe_impl_from_macro { + unsafe trait T {} + + // error + macro_rules! no_safety_comment { + ($t:ty) => { + unsafe impl T for $t {} + }; + } + + // ok + no_safety_comment!(()); + + // ok + macro_rules! with_safety_comment { + ($t:ty) => { + // SAFETY: + unsafe impl T for $t {} + }; + } + + // ok + with_safety_comment!((i32)); +} + +mod unsafe_impl_macro_and_not_macro { + unsafe trait T {} + + // error + macro_rules! no_safety_comment { + ($t:ty) => { + unsafe impl T for $t {} + }; + } + + // ok + no_safety_comment!(()); + + // error + unsafe impl T for (i32) {} + + // ok + no_safety_comment!(u32); + + // error + unsafe impl T for (bool) {} +} + +#[rustfmt::skip] +mod unsafe_impl_valid_comment { + unsafe trait SaFety {} + // SaFety: + unsafe impl SaFety for () {} + + unsafe trait MultiLineComment {} + // The following impl is safe + // ... + // Safety: reason + unsafe impl MultiLineComment for () {} + + unsafe trait NoAscii {} + // 安全 SAFETY: 以下のコードは安全です + unsafe impl NoAscii for () {} + + unsafe trait InlineAndPrecedingComment {} + // SAFETY: + /* comment */ unsafe impl InlineAndPrecedingComment for () {} + + unsafe trait BuriedSafety {} + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor + // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation + // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in + // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint + // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + // laborum. Safety: + // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi + // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio + // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl + // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus. + unsafe impl BuriedSafety for () {} + + unsafe trait MultiLineBlockComment {} + /* This is a description + * Safety: */ + unsafe impl MultiLineBlockComment for () {} +} + +#[rustfmt::skip] +mod unsafe_impl_invalid_comment { + unsafe trait NoComment {} + + unsafe impl NoComment for () {} + + unsafe trait InlineComment {} + + /* SAFETY: */ unsafe impl InlineComment for () {} + + unsafe trait TrailingComment {} + + unsafe impl TrailingComment for () {} // SAFETY: + + unsafe trait Interference {} + // SAFETY: + const BIG_NUMBER: i32 = 1000000; + unsafe impl Interference for () {} +} + +unsafe trait ImplInFn {} + +fn impl_in_fn() { + // error + unsafe impl ImplInFn for () {} + + // SAFETY: ok + unsafe impl ImplInFn for (i32) {} +} + +unsafe trait CrateRoot {} + +// error +unsafe impl CrateRoot for () {} + +// SAFETY: ok +unsafe impl CrateRoot for (i32) {} + +fn issue_9142() { + // SAFETY: ok + let _ = + // we need this comment to avoid rustfmt putting + // it all on one line + unsafe {}; + + // SAFETY: this is more than one level away, so it should warn + let _ = { + if unsafe { true } { + todo!(); + } else { + let bar = unsafe {}; + todo!(); + bar + } + }; +======= +#![deny(clippy::undocumented_unsafe_blocks)] +#![allow(clippy::missing_safety_doc)] +======= +//@aux-build:proc_macro_unsafe.rs +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= +//@aux-build:proc_macro_unsafe.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) + +#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)] +#![allow(deref_nullptr, clippy::let_unit_value, clippy::missing_safety_doc)] +#![feature(lint_reasons)] + +extern crate proc_macro_unsafe; + +// Valid comments + +fn nested_local() { + let _ = { + let _ = { + // SAFETY: + let _ = unsafe {}; + }; + }; +} + +fn deep_nest() { + let _ = { + let _ = { + // SAFETY: + let _ = unsafe {}; + + // Safety: + unsafe {}; + + let _ = { + let _ = { + let _ = { + let _ = { + let _ = { + // Safety: + let _ = unsafe {}; + + // SAFETY: + unsafe {}; + }; + }; + }; + + // Safety: + unsafe {}; + }; + }; + }; + + // Safety: + unsafe {}; + }; + + // SAFETY: + unsafe {}; +} + +fn local_tuple_expression() { + // Safety: + let _ = (42, unsafe {}); +} + +fn line_comment() { + // Safety: + unsafe {} +} + +fn line_comment_newlines() { + // SAFETY: + + unsafe {} +} + +fn line_comment_empty() { + // Safety: + // + // + // + unsafe {} +} + +fn line_comment_with_extras() { + // This is a description + // Safety: + unsafe {} +} + +fn block_comment() { + /* Safety: */ + unsafe {} +} + +fn block_comment_newlines() { + /* SAFETY: */ + + unsafe {} +} + +fn block_comment_with_extras() { + /* This is a description + * SAFETY: + */ + unsafe {} +} + +fn block_comment_terminator_same_line() { + /* This is a description + * Safety: */ + unsafe {} +} + +fn buried_safety() { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor + // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation + // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in + // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint + // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + // laborum. Safety: + // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi + // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio + // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl + // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus. + unsafe {} +} + +fn safety_with_prepended_text() { + // This is a test. safety: + unsafe {} +} + +fn local_line_comment() { + // Safety: + let _ = unsafe {}; +} + +fn local_block_comment() { + /* SAFETY: */ + let _ = unsafe {}; +} + +fn comment_array() { + // Safety: + let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; +} + +fn comment_tuple() { + // sAFETY: + let _ = (42, unsafe {}, "test", unsafe {}); +} + +fn comment_unary() { + // SAFETY: + let _ = *unsafe { &42 }; +} + +#[allow(clippy::match_single_binding)] +fn comment_match() { + // SAFETY: + let _ = match unsafe {} { + _ => {}, + }; +} + +fn comment_addr_of() { + // Safety: + let _ = &unsafe {}; +} + +fn comment_repeat() { + // Safety: + let _ = [unsafe {}; 5]; +} + +fn comment_macro_call() { + macro_rules! t { + ($b:expr) => { + $b + }; + } + + t!( + // SAFETY: + unsafe {} + ); +} + +fn comment_macro_def() { + macro_rules! t { + () => { + // Safety: + unsafe {} + }; + } + + t!(); +} + +fn non_ascii_comment() { + // ॐ᧻໒ SaFeTy: ௵∰ + unsafe {}; +} + +fn local_commented_block() { + let _ = + // safety: + unsafe {}; +} + +fn local_nest() { + // safety: + let _ = [(42, unsafe {}, unsafe {}), (52, unsafe {}, unsafe {})]; +} + +fn in_fn_call(x: *const u32) { + fn f(x: u32) {} + + // Safety: reason + f(unsafe { *x }); +} + +fn multi_in_fn_call(x: *const u32) { + fn f(x: u32, y: u32) {} + + // Safety: reason + f(unsafe { *x }, unsafe { *x }); +} + +fn in_multiline_fn_call(x: *const u32) { + fn f(x: u32, y: u32) {} + + f( + // Safety: reason + unsafe { *x }, + 0, + ); +} + +fn in_macro_call(x: *const u32) { + // Safety: reason + println!("{}", unsafe { *x }); +} + +fn in_multiline_macro_call(x: *const u32) { + println!( + "{}", + // Safety: reason + unsafe { *x }, + ); +} + +fn from_proc_macro() { + proc_macro_unsafe::unsafe_block!(token); +} + +fn in_closure(x: *const u32) { + // Safety: reason + let _ = || unsafe { *x }; +} + +// Invalid comments + +#[rustfmt::skip] +fn inline_block_comment() { + /* Safety: */ unsafe {} +} + +fn no_comment() { + unsafe {} +} + +fn no_comment_array() { + let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; +} + +fn no_comment_tuple() { + let _ = (42, unsafe {}, "test", unsafe {}); +} + +fn no_comment_unary() { + let _ = *unsafe { &42 }; +} + +#[allow(clippy::match_single_binding)] +fn no_comment_match() { + let _ = match unsafe {} { + _ => {}, + }; +} + +fn no_comment_addr_of() { + let _ = &unsafe {}; +} + +fn no_comment_repeat() { + let _ = [unsafe {}; 5]; +} + +fn local_no_comment() { + let _ = unsafe {}; +} + +fn no_comment_macro_call() { + macro_rules! t { + ($b:expr) => { + $b + }; + } + + t!(unsafe {}); +} + +fn no_comment_macro_def() { + macro_rules! t { + () => { + unsafe {} + }; + } + + t!(); +} + +fn trailing_comment() { + unsafe {} // SAFETY: +} + +fn internal_comment() { + unsafe { + // SAFETY: + } +} + +fn interference() { + // SAFETY + + let _ = 42; + + unsafe {}; +} + +pub fn print_binary_tree() { + println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); +} + +mod unsafe_impl_smoke_test { + unsafe trait A {} + + // error: no safety comment + unsafe impl A for () {} + + // Safety: ok + unsafe impl A for (i32) {} + + mod sub_mod { + // error: + unsafe impl B for (u32) {} + unsafe trait B {} + } + + #[rustfmt::skip] + mod sub_mod2 { + // + // SAFETY: ok + // + + unsafe impl B for (u32) {} + unsafe trait B {} + } +} + +mod unsafe_impl_from_macro { + unsafe trait T {} + + // error + macro_rules! no_safety_comment { + ($t:ty) => { + unsafe impl T for $t {} + }; + } + + // ok + no_safety_comment!(()); + + // ok + macro_rules! with_safety_comment { + ($t:ty) => { + // SAFETY: + unsafe impl T for $t {} + }; + } + + // ok + with_safety_comment!((i32)); +} + +mod unsafe_impl_macro_and_not_macro { + unsafe trait T {} + + // error + macro_rules! no_safety_comment { + ($t:ty) => { + unsafe impl T for $t {} + }; + } + + // ok + no_safety_comment!(()); + + // error + unsafe impl T for (i32) {} + + // ok + no_safety_comment!(u32); + + // error + unsafe impl T for (bool) {} +} + +#[rustfmt::skip] +mod unsafe_impl_valid_comment { + unsafe trait SaFety {} + // SaFety: + unsafe impl SaFety for () {} + + unsafe trait MultiLineComment {} + // The following impl is safe + // ... + // Safety: reason + unsafe impl MultiLineComment for () {} + + unsafe trait NoAscii {} + // 安全 SAFETY: 以下のコードは安全です + unsafe impl NoAscii for () {} + + unsafe trait InlineAndPrecedingComment {} + // SAFETY: + /* comment */ unsafe impl InlineAndPrecedingComment for () {} + + unsafe trait BuriedSafety {} + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor + // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation + // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in + // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint + // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + // laborum. Safety: + // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi + // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio + // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl + // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus. + unsafe impl BuriedSafety for () {} + + unsafe trait MultiLineBlockComment {} + /* This is a description + * Safety: */ + unsafe impl MultiLineBlockComment for () {} +} + +#[rustfmt::skip] +mod unsafe_impl_invalid_comment { + unsafe trait NoComment {} + + unsafe impl NoComment for () {} + + unsafe trait InlineComment {} + + /* SAFETY: */ unsafe impl InlineComment for () {} + + unsafe trait TrailingComment {} + + unsafe impl TrailingComment for () {} // SAFETY: + + unsafe trait Interference {} + // SAFETY: + const BIG_NUMBER: i32 = 1000000; + unsafe impl Interference for () {} +} + +unsafe trait ImplInFn {} + +fn impl_in_fn() { + // error + unsafe impl ImplInFn for () {} + + // SAFETY: ok + unsafe impl ImplInFn for (i32) {} +} + +unsafe trait CrateRoot {} + +// error +unsafe impl CrateRoot for () {} + +// SAFETY: ok +unsafe impl CrateRoot for (i32) {} + +fn issue_9142() { + // SAFETY: ok + let _ = + // we need this comment to avoid rustfmt putting + // it all on one line + unsafe {}; + + // SAFETY: this is more than one level away, so it should warn + let _ = { + if unsafe { true } { + todo!(); + } else { + let bar = unsafe {}; + todo!(); + bar + } + }; +} + +pub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 { + 1 +} + +pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -> u32 { + 2 +} + +fn issue_10832() { + // Safety: A safety comment + let _some_variable_with_a_very_long_name_to_break_the_line = + unsafe { a_function_with_a_very_long_name_to_break_the_line() }; +<<<<<<< HEAD +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= + + // Safety: Another safety comment + const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + + // Safety: Yet another safety comment + static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; +>>>>>>> e2e6a0244 (Addressing reviewer comments) +} + +pub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 { + 1 +} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> e2e6a0244 (Addressing reviewer comments) + +pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -> u32 { + 2 +} +<<<<<<< HEAD + +fn issue_10832() { + // Safety: A safety comment + let _some_variable_with_a_very_long_name_to_break_the_line = + unsafe { a_function_with_a_very_long_name_to_break_the_line() }; + + // Safety: Another safety comment + const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + + // Safety: Yet another safety comment + static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> cc2e49f69 (allow safety comment above attributes) +fn issue_8679() { + // SAFETY: + #[allow(unsafe_code)] + unsafe {} + + // SAFETY: + #[expect(unsafe_code, reason = "totally safe")] + unsafe { + *std::ptr::null::() + }; + + // Safety: A safety comment + #[allow(unsafe_code)] + let _some_variable_with_a_very_long_name_to_break_the_line = + unsafe { a_function_with_a_very_long_name_to_break_the_line() }; + + // Safety: Another safety comment + #[allow(unsafe_code)] + const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + + // Safety: Yet another safety comment + #[allow(unsafe_code)] + static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + + // SAFETY: + #[allow(unsafe_code)] + // This also works I guess + unsafe {} +} + +fn main() {} +======= +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= +>>>>>>> e2e6a0244 (Addressing reviewer comments) +======= +fn main() {} +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr new file mode 100644 index 000000000000..80dba7a89fba --- /dev/null +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr @@ -0,0 +1,610 @@ +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:263:19 +======= + --> $DIR/undocumented_unsafe_blocks.rs:262:19 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:263:19 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | /* Safety: */ unsafe {} + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings` + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:267:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:266:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:267:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe {} + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:271:14 +======= + --> $DIR/undocumented_unsafe_blocks.rs:270:14 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:271:14 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; + | ^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:271:29 +======= + --> $DIR/undocumented_unsafe_blocks.rs:270:29 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:271:29 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; + | ^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:271:48 +======= + --> $DIR/undocumented_unsafe_blocks.rs:270:48 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:271:48 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; + | ^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:275:18 +======= + --> $DIR/undocumented_unsafe_blocks.rs:274:18 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:275:18 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | let _ = (42, unsafe {}, "test", unsafe {}); + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:275:37 +======= + --> $DIR/undocumented_unsafe_blocks.rs:274:37 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:275:37 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | let _ = (42, unsafe {}, "test", unsafe {}); + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:279:14 +======= + --> $DIR/undocumented_unsafe_blocks.rs:278:14 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:279:14 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | let _ = *unsafe { &42 }; + | ^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:284:19 +======= + --> $DIR/undocumented_unsafe_blocks.rs:283:19 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:284:19 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | let _ = match unsafe {} { + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:290:14 +======= + --> $DIR/undocumented_unsafe_blocks.rs:289:14 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:290:14 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | let _ = &unsafe {}; + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:294:14 +======= + --> $DIR/undocumented_unsafe_blocks.rs:293:14 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:294:14 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | let _ = [unsafe {}; 5]; + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:298:13 +======= + --> $DIR/undocumented_unsafe_blocks.rs:297:13 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:298:13 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | let _ = unsafe {}; + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:308:8 +======= + --> $DIR/undocumented_unsafe_blocks.rs:307:8 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:308:8 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | t!(unsafe {}); + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:314:13 +======= + --> $DIR/undocumented_unsafe_blocks.rs:313:13 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:314:13 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe {} + | ^^^^^^^^^ +... +LL | t!(); + | ---- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:322:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:321:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:322:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe {} // SAFETY: + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:326:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:325:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:326:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe { + | ^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:336:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:335:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:336:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe {}; + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:340:20 +======= + --> $DIR/undocumented_unsafe_blocks.rs:339:20 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:340:20 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:347:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:346:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:347:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl A for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:354:9 +======= + --> $DIR/undocumented_unsafe_blocks.rs:353:9 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:354:9 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl B for (u32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:375:13 +======= + --> $DIR/undocumented_unsafe_blocks.rs:374:13 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:375:13 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl T for $t {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | no_safety_comment!(()); + | ---------------------- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:400:13 +======= + --> $DIR/undocumented_unsafe_blocks.rs:399:13 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:400:13 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl T for $t {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | no_safety_comment!(()); + | ---------------------- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:408:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:407:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:408:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl T for (i32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:400:13 +======= + --> $DIR/undocumented_unsafe_blocks.rs:399:13 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:400:13 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl T for $t {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | no_safety_comment!(u32); + | ----------------------- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:414:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:413:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:414:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl T for (bool) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:460:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:459:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:460:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl NoComment for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:464:19 +======= + --> $DIR/undocumented_unsafe_blocks.rs:463:19 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:464:19 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | /* SAFETY: */ unsafe impl InlineComment for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:468:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:467:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:468:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl TrailingComment for () {} // SAFETY: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: constant item has unnecessary safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:472:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:471:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:472:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | const BIG_NUMBER: i32 = 1000000; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider removing the safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:471:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:470:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:471:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | // SAFETY: + | ^^^^^^^^^^ + = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings` + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:473:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:472:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:473:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl Interference for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:480:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:479:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:480:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl ImplInFn for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:489:1 +======= + --> $DIR/undocumented_unsafe_blocks.rs:488:1 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:489:1 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | unsafe impl CrateRoot for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: statement has unnecessary safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:502:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:501:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:502:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | / let _ = { +LL | | if unsafe { true } { +LL | | todo!(); +LL | | } else { +... | +LL | | } +LL | | }; + | |______^ + | +help: consider removing the safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:501:5 +======= + --> $DIR/undocumented_unsafe_blocks.rs:500:5 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:501:5 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | // SAFETY: this is more than one level away, so it should warn + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:503:12 +======= + --> $DIR/undocumented_unsafe_blocks.rs:502:12 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:503:12 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | if unsafe { true } { + | ^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:506:23 +======= + --> $DIR/undocumented_unsafe_blocks.rs:505:23 +>>>>>>> 8625a849d (adding all ui tests to the configuration test as well) +======= + --> $DIR/undocumented_unsafe_blocks.rs:506:23 +>>>>>>> cc2e49f69 (allow safety comment above attributes) + | +LL | let bar = unsafe {}; + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: aborting due to 35 previous errors + diff --git a/tests/ui-toml/unwrap_used/unwrap_used.rs b/tests/ui-toml/unwrap_used/unwrap_used.rs index 6525ea5bfc3f..e300ba18c330 100644 --- a/tests/ui-toml/unwrap_used/unwrap_used.rs +++ b/tests/ui-toml/unwrap_used/unwrap_used.rs @@ -1,12 +1,15 @@ -// compile-flags: --test +//@compile-flags: --test -#![allow(unused_mut, clippy::get_first, clippy::from_iter_instead_of_collect)] +#![allow( + unused_mut, + clippy::get_first, + clippy::from_iter_instead_of_collect, + clippy::useless_vec +)] #![warn(clippy::unwrap_used)] -#![deny(clippy::get_unwrap)] +#![warn(clippy::get_unwrap)] -use std::collections::BTreeMap; -use std::collections::HashMap; -use std::collections::VecDeque; +use std::collections::{BTreeMap, HashMap, VecDeque}; struct GetFalsePositive { arr: [u32; 3], diff --git a/tests/ui-toml/unwrap_used/unwrap_used.stderr b/tests/ui-toml/unwrap_used/unwrap_used.stderr index 8a32750e3c92..a08bab368444 100644 --- a/tests/ui-toml/unwrap_used/unwrap_used.stderr +++ b/tests/ui-toml/unwrap_used/unwrap_used.stderr @@ -1,17 +1,25 @@ error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:35:17 + --> $DIR/unwrap_used.rs:38:17 | LL | let _ = boxed_slice.get(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&boxed_slice[1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&boxed_slice[1]` | +<<<<<<< HEAD +<<<<<<< HEAD + = note: `-D clippy::get-unwrap` implied by `-D warnings` +======= note: the lint level is defined here - --> $DIR/unwrap_used.rs:5:9 + --> $DIR/unwrap_used.rs:10:9 | LL | #![deny(clippy::get_unwrap)] | ^^^^^^^^^^^^^^^^^^ +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + = note: `-D clippy::get-unwrap` implied by `-D warnings` +>>>>>>> 5bd97ac17 (Update tests) error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:35:17 + --> $DIR/unwrap_used.rs:38:17 | LL | let _ = boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,13 +28,13 @@ LL | let _ = boxed_slice.get(1).unwrap(); = note: `-D clippy::unwrap-used` implied by `-D warnings` error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:36:17 + --> $DIR/unwrap_used.rs:39:17 | LL | let _ = some_slice.get(0).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_slice[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_slice[0]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:36:17 + --> $DIR/unwrap_used.rs:39:17 | LL | let _ = some_slice.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,13 +42,13 @@ LL | let _ = some_slice.get(0).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:37:17 + --> $DIR/unwrap_used.rs:40:17 | LL | let _ = some_vec.get(0).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vec[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_vec[0]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:37:17 + --> $DIR/unwrap_used.rs:40:17 | LL | let _ = some_vec.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,13 +56,13 @@ LL | let _ = some_vec.get(0).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:38:17 + --> $DIR/unwrap_used.rs:41:17 | LL | let _ = some_vecdeque.get(0).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vecdeque[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_vecdeque[0]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:38:17 + --> $DIR/unwrap_used.rs:41:17 | LL | let _ = some_vecdeque.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -62,13 +70,13 @@ LL | let _ = some_vecdeque.get(0).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:39:17 + --> $DIR/unwrap_used.rs:42:17 | LL | let _ = some_hashmap.get(&1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_hashmap[&1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_hashmap[&1]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:39:17 + --> $DIR/unwrap_used.rs:42:17 | LL | let _ = some_hashmap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -76,13 +84,13 @@ LL | let _ = some_hashmap.get(&1).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:40:17 + --> $DIR/unwrap_used.rs:43:17 | LL | let _ = some_btreemap.get(&1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_btreemap[&1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_btreemap[&1]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:40:17 + --> $DIR/unwrap_used.rs:43:17 | LL | let _ = some_btreemap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,13 +98,13 @@ LL | let _ = some_btreemap.get(&1).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:44:21 + --> $DIR/unwrap_used.rs:47:21 | LL | let _: u8 = *boxed_slice.get(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice[1]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:44:22 + --> $DIR/unwrap_used.rs:47:22 | LL | let _: u8 = *boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,13 +112,13 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:49:9 + --> $DIR/unwrap_used.rs:52:9 | LL | *boxed_slice.get_mut(0).unwrap() = 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice[0]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:49:10 + --> $DIR/unwrap_used.rs:52:10 | LL | *boxed_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,13 +126,13 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:50:9 + --> $DIR/unwrap_used.rs:53:9 | LL | *some_slice.get_mut(0).unwrap() = 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_slice[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_slice[0]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:50:10 + --> $DIR/unwrap_used.rs:53:10 | LL | *some_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,13 +140,13 @@ LL | *some_slice.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:51:9 + --> $DIR/unwrap_used.rs:54:9 | LL | *some_vec.get_mut(0).unwrap() = 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:51:10 + --> $DIR/unwrap_used.rs:54:10 | LL | *some_vec.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -146,13 +154,13 @@ LL | *some_vec.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:52:9 + --> $DIR/unwrap_used.rs:55:9 | LL | *some_vecdeque.get_mut(0).unwrap() = 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vecdeque[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vecdeque[0]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:52:10 + --> $DIR/unwrap_used.rs:55:10 | LL | *some_vecdeque.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -160,13 +168,13 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:64:17 + --> $DIR/unwrap_used.rs:67:17 | LL | let _ = some_vec.get(0..1).unwrap().to_vec(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0..1]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:64:17 + --> $DIR/unwrap_used.rs:67:17 | LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,13 +182,13 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:65:17 + --> $DIR/unwrap_used.rs:68:17 | LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0..1]` error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_used.rs:65:17 + --> $DIR/unwrap_used.rs:68:17 | LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -188,16 +196,16 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:72:13 + --> $DIR/unwrap_used.rs:75:13 | LL | let _ = boxed_slice.get(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&boxed_slice[1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&boxed_slice[1]` error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/unwrap_used.rs:90:17 + --> $DIR/unwrap_used.rs:93:17 | LL | let _ = Box::new([0]).get(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&Box::new([0])[1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&Box::new([0])[1]` error: aborting due to 28 previous errors diff --git a/tests/ui-toml/update-all-references.sh b/tests/ui-toml/update-all-references.sh index 4391499a1e1f..d42043070261 100755 --- a/tests/ui-toml/update-all-references.sh +++ b/tests/ui-toml/update-all-references.sh @@ -1,3 +1,3 @@ #!/bin/bash -echo "Please use 'cargo dev bless' instead." +echo "Please use 'cargo bless' instead." diff --git a/tests/ui/allow_attributes.fixed b/tests/ui/allow_attributes.fixed index b8dd0619e6d0..28601f2222a9 100644 --- a/tests/ui/allow_attributes.fixed +++ b/tests/ui/allow_attributes.fixed @@ -1,9 +1,23 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(unused)] #![warn(clippy::allow_attributes)] #![feature(lint_reasons)] +#![no_main] -fn main() {} +extern crate proc_macros; +use proc_macros::{external, with_span}; // Using clippy::needless_borrow just as a placeholder, it isn't relevant. @@ -20,6 +34,29 @@ struct T4; #[cfg_attr(panic = "unwind", expect(dead_code))] struct CfgT; +fn ignore_external() { + external! { +<<<<<<< HEAD +<<<<<<< HEAD + #[allow(clippy::needless_borrow)] // Should not lint +======= + #[allow(clippy::needless_borrow)] +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= + #[allow(clippy::needless_borrow)] // Should not lint +>>>>>>> ab70553a3 (foiled again (forgot to run cargo test)) + fn a() {} + } +} + +fn ignore_proc_macro() { + with_span! { + span + #[allow(clippy::needless_borrow)] // Should not lint + fn a() {} + } +} + fn ignore_inner_attr() { #![allow(unused)] // Should not lint } diff --git a/tests/ui/allow_attributes.rs b/tests/ui/allow_attributes.rs index 295f560906a7..03a7e39823e8 100644 --- a/tests/ui/allow_attributes.rs +++ b/tests/ui/allow_attributes.rs @@ -1,9 +1,23 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(unused)] #![warn(clippy::allow_attributes)] #![feature(lint_reasons)] +#![no_main] -fn main() {} +extern crate proc_macros; +use proc_macros::{external, with_span}; // Using clippy::needless_borrow just as a placeholder, it isn't relevant. @@ -20,6 +34,21 @@ struct T4; #[cfg_attr(panic = "unwind", allow(dead_code))] struct CfgT; +fn ignore_external() { + external! { + #[allow(clippy::needless_borrow)] // Should not lint + fn a() {} + } +} + +fn ignore_proc_macro() { + with_span! { + span + #[allow(clippy::needless_borrow)] // Should not lint + fn a() {} + } +} + fn ignore_inner_attr() { #![allow(unused)] // Should not lint } diff --git a/tests/ui/allow_attributes.stderr b/tests/ui/allow_attributes.stderr index 681837e9ed77..138b5fee5f9a 100644 --- a/tests/ui/allow_attributes.stderr +++ b/tests/ui/allow_attributes.stderr @@ -1,16 +1,26 @@ error: #[allow] attribute found - --> $DIR/allow_attributes.rs:11:3 + --> $DIR/allow_attributes.rs:14:3 | LL | #[allow(dead_code)] | ^^^^^ help: replace it with: `expect` | = note: `-D clippy::allow-attributes` implied by `-D warnings` +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 497f37793 (Fix `attr_search_pat` for `#[cfg_attr]`) error: #[allow] attribute found - --> $DIR/allow_attributes.rs:20:30 + --> $DIR/allow_attributes.rs:23:30 | LL | #[cfg_attr(panic = "unwind", allow(dead_code))] | ^^^^^ help: replace it with: `expect` error: aborting due to 2 previous errors +<<<<<<< HEAD +======= +error: aborting due to previous error +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= +>>>>>>> 497f37793 (Fix `attr_search_pat` for `#[cfg_attr]`) diff --git a/tests/ui/allow_attributes_false_positive.rs b/tests/ui/allow_attributes_false_positive.rs new file mode 100644 index 000000000000..b72fdbc28b1f --- /dev/null +++ b/tests/ui/allow_attributes_false_positive.rs @@ -0,0 +1,15 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +#![allow(unused)] +>>>>>>> 85d7de25a (fix false positive) +======= +>>>>>>> 3045998bc (Update allow_attributes_false_positive.rs) +======= +>>>>>>> 4da6e7e06 (rebase attempt) +#![warn(clippy::allow_attributes)] +#![feature(lint_reasons)] +#![crate_type = "proc-macro"] + +fn main() {} diff --git a/tests/ui/allow_attributes_without_reason.rs b/tests/ui/allow_attributes_without_reason.rs index 1a0d4e886576..1c171b43167d 100644 --- a/tests/ui/allow_attributes_without_reason.rs +++ b/tests/ui/allow_attributes_without_reason.rs @@ -1,9 +1,23 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) #![feature(lint_reasons)] #![deny(clippy::allow_attributes_without_reason)] +#![allow(unfulfilled_lint_expectations)] + +extern crate proc_macros; +use proc_macros::{external, with_span}; // These should trigger the lint #[allow(dead_code)] #[allow(dead_code, deprecated)] +#[expect(dead_code)] // These should be fine #[allow(dead_code, reason = "This should be allowed")] #[warn(dyn_drop, reason = "Warnings can also have reasons")] @@ -11,4 +25,45 @@ #[deny(deref_nullptr)] #[forbid(deref_nullptr)] -fn main() {} +fn main() { + external! { + #[allow(dead_code)] + fn a() {} + } + with_span! { + span + #[allow(dead_code)] + fn b() {} + } +} +<<<<<<< HEAD +<<<<<<< HEAD + +// Make sure this is not triggered on `?` desugaring + +pub fn trigger_fp_option() -> Option<()> { +======= + +// Make sure this is not triggered on `?` desugaring + +<<<<<<< HEAD +pub fn trigger_fp_option() -> Option<()>{ +>>>>>>> 70553711a (add test for `?` desugaring) +======= +pub fn trigger_fp_option() -> Option<()> { +>>>>>>> b469e8ce2 (Update allow_attributes_without_reason.rs) + Some(())?; + None?; + Some(()) +} + +pub fn trigger_fp_result() -> Result<(), &'static str> { + Ok(())?; + Err("asdf")?; + Ok(()) +} +<<<<<<< HEAD +======= +>>>>>>> 0086b6ab0 (don't lint `allow_attributes` on attributes from proc macros) +======= +>>>>>>> 70553711a (add test for `?` desugaring) diff --git a/tests/ui/allow_attributes_without_reason.stderr b/tests/ui/allow_attributes_without_reason.stderr index 23f17e9a7afb..96f747d0026d 100644 --- a/tests/ui/allow_attributes_without_reason.stderr +++ b/tests/ui/allow_attributes_without_reason.stderr @@ -1,23 +1,39 @@ error: `allow` attribute without specifying a reason - --> $DIR/allow_attributes_without_reason.rs:5:1 + --> $DIR/allow_attributes_without_reason.rs:4:1 | -LL | #[allow(dead_code)] - | ^^^^^^^^^^^^^^^^^^^ +LL | #![allow(unfulfilled_lint_expectations)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try adding a reason at the end with `, reason = ".."` note: the lint level is defined here - --> $DIR/allow_attributes_without_reason.rs:2:9 + --> $DIR/allow_attributes_without_reason.rs:3:9 | LL | #![deny(clippy::allow_attributes_without_reason)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `allow` attribute without specifying a reason - --> $DIR/allow_attributes_without_reason.rs:6:1 + --> $DIR/allow_attributes_without_reason.rs:10:1 + | +LL | #[allow(dead_code)] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a reason at the end with `, reason = ".."` + +error: `allow` attribute without specifying a reason + --> $DIR/allow_attributes_without_reason.rs:11:1 | LL | #[allow(dead_code, deprecated)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try adding a reason at the end with `, reason = ".."` -error: aborting due to 2 previous errors +error: `expect` attribute without specifying a reason + --> $DIR/allow_attributes_without_reason.rs:12:1 + | +LL | #[expect(dead_code)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a reason at the end with `, reason = ".."` + +error: aborting due to 4 previous errors diff --git a/tests/ui/almost_complete_range.fixed b/tests/ui/almost_complete_range.fixed index a4bf7fe18d5f..882ac8007b3c 100644 --- a/tests/ui/almost_complete_range.fixed +++ b/tests/ui/almost_complete_range.fixed @@ -1,6 +1,10 @@ -// run-rustfix -// edition:2018 -// aux-build:proc_macros.rs +//@run-rustfix +//@edition:2018 +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(exclusive_range_pattern)] #![feature(stmt_expr_attributes)] diff --git a/tests/ui/almost_complete_range.rs b/tests/ui/almost_complete_range.rs index 8237c3a13611..ccbc8bd55440 100644 --- a/tests/ui/almost_complete_range.rs +++ b/tests/ui/almost_complete_range.rs @@ -1,6 +1,10 @@ -// run-rustfix -// edition:2018 -// aux-build:proc_macros.rs +//@run-rustfix +//@edition:2018 +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(exclusive_range_pattern)] #![feature(stmt_expr_attributes)] diff --git a/tests/ui/arc_with_non_send_sync.rs b/tests/ui/arc_with_non_send_sync.rs new file mode 100644 index 000000000000..e3fe436d99fd --- /dev/null +++ b/tests/ui/arc_with_non_send_sync.rs @@ -0,0 +1,33 @@ +#![warn(clippy::arc_with_non_send_sync)] +#![allow(unused_variables)] +use std::cell::RefCell; +use std::sync::{Arc, Mutex}; + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2f5d1c748 (Adding extra check to ignore generic args.) +fn foo(x: T) { + // Should not lint - purposefully ignoring generic args. + let a = Arc::new(x); +} +fn issue11076() { + let a: Arc> = Arc::new(Vec::new()); +} + +<<<<<<< HEAD +======= +>>>>>>> 339cd14f2 (Adds new lint `arc_with_non_send_or_sync`) +======= +>>>>>>> 2f5d1c748 (Adding extra check to ignore generic args.) +fn main() { + let _ = Arc::new(42); + + // !Sync + let _ = Arc::new(RefCell::new(42)); + let mutex = Mutex::new(1); + // !Send + let _ = Arc::new(mutex.lock().unwrap()); + // !Send + !Sync + let _ = Arc::new(&42 as *const i32); +} diff --git a/tests/ui/arc_with_non_send_sync.stderr b/tests/ui/arc_with_non_send_sync.stderr new file mode 100644 index 000000000000..fe9df82268ef --- /dev/null +++ b/tests/ui/arc_with_non_send_sync.stderr @@ -0,0 +1,63 @@ +<<<<<<< HEAD +error: usage of `Arc` where `T` is not `Send` or `Sync` +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arc_with_non_send_sync.rs:16:13 +======= + --> $DIR/arc_with_non_send_sync.rs:11:13 +>>>>>>> 339cd14f2 (Adds new lint `arc_with_non_send_or_sync`) +======= + --> $DIR/arc_with_non_send_sync.rs:16:13 +>>>>>>> 2f5d1c748 (Adding extra check to ignore generic args.) +======= + --> $DIR/arc_with_non_send_sync.rs:19:13 +>>>>>>> 75c339cd0 ([`arc_with_non_send_sync`]: look for nested type parameters) +======= +error: usage of an `Arc` that is not `Send` or `Sync` + --> $DIR/arc_with_non_send_sync.rs:18:13 +>>>>>>> 4939a716e (arc_with_non_send_sync: reword and move to suspicious) + | +LL | let _ = Arc::new(RefCell::new(42)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + = help: consider using `Rc` instead or wrapping `T` in a std::sync type like `Mutex` +======= + = help: consider using `Rc` instead or wrapping `T` in a std::sync type like Mutex +>>>>>>> 339cd14f2 (Adds new lint `arc_with_non_send_or_sync`) +======= + = help: consider using `Rc` instead or wrapping `T` in a std::sync type like `Mutex` +>>>>>>> 2f5d1c748 (Adding extra check to ignore generic args.) +======= + = note: the trait `Sync` is not implemented for `RefCell` + = note: required for `Arc>` to implement `Send` and `Sync` + = help: consider using an `Rc` instead or wrapping the inner type with a `Mutex` +>>>>>>> 4939a716e (arc_with_non_send_sync: reword and move to suspicious) + = note: `-D clippy::arc-with-non-send-sync` implied by `-D warnings` + +error: usage of an `Arc` that is not `Send` or `Sync` + --> $DIR/arc_with_non_send_sync.rs:21:13 + | +LL | let _ = Arc::new(mutex.lock().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the trait `Send` is not implemented for `MutexGuard<'_, i32>` + = note: required for `Arc>` to implement `Send` and `Sync` + = help: consider using an `Rc` instead or wrapping the inner type with a `Mutex` + +error: usage of an `Arc` that is not `Send` or `Sync` + --> $DIR/arc_with_non_send_sync.rs:23:13 + | +LL | let _ = Arc::new(&42 as *const i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the trait `Send` is not implemented for `*const i32` + = note: the trait `Sync` is not implemented for `*const i32` + = note: required for `Arc<*const i32>` to implement `Send` and `Sync` + = help: consider using an `Rc` instead or wrapping the inner type with a `Mutex` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/arithmetic_side_effects.rs b/tests/ui/arithmetic_side_effects.rs index 3c06676d7228..22a8dc6bead4 100644 --- a/tests/ui/arithmetic_side_effects.rs +++ b/tests/ui/arithmetic_side_effects.rs @@ -1,3 +1,44 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs +======= +// aux-build:proc_macro_derive.rs +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +// aux-build:proc_macro_derive.rs +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +//@aux-build:proc_macro_derive.rs:proc-macro +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +//@aux-build:proc_macro_derive.rs:proc-macro +======= +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs +======= +// aux-build:proc_macro_derive.rs +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + #![allow( clippy::assign_op_pattern, clippy::erasing_op, @@ -11,6 +52,8 @@ #![feature(const_mut_refs, inline_const, saturating_int_impl)] #![warn(clippy::arithmetic_side_effects)] +extern crate proc_macro_derive; + use core::num::{Saturating, Wrapping}; const ONE: i32 = 1; @@ -19,6 +62,9 @@ const ZERO: i32 = 0; #[derive(Clone, Copy)] pub struct Custom; +#[derive(proc_macro_derive::ShadowDerive)] +pub struct Nothing; + macro_rules! impl_arith { ( $( $_trait:ident, $lhs:ty, $rhs:ty, $method:ident; )* ) => { $( @@ -269,6 +315,17 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri _n = &1 * _n; _n = 23 + 85; + // Method + _n.saturating_div(1); + _n.wrapping_div(1); + _n.wrapping_rem(1); + _n.wrapping_rem_euclid(1); + + _n.saturating_div(1); + _n.checked_div(1); + _n.checked_rem(1); + _n.checked_rem_euclid(1); + // Unary _n = -2147483647; _n = -i32::MAX; @@ -376,6 +433,17 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() { _custom = Custom << _custom; _custom = &Custom << _custom; + // Method + _n.saturating_div(0); + _n.wrapping_div(0); + _n.wrapping_rem(0); + _n.wrapping_rem_euclid(0); + + _n.saturating_div(_n); + _n.wrapping_div(_n); + _n.wrapping_rem(_n); + _n.wrapping_rem_euclid(_n); + // Unary _n = -_n; _n = -&_n; @@ -429,4 +497,52 @@ pub fn issue_10583(a: u16) -> u16 { 10 / a } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 891fffef0 (Consider referenced allowed or hard-coded types) +pub fn issue_10767() { + let n = &1.0; + n + n; + 3.1_f32 + &1.2_f32; + &3.4_f32 + 1.5_f32; + &3.5_f32 + &1.3_f32; +} + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +>>>>>>> 891fffef0 (Consider referenced allowed or hard-coded types) +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +pub fn issue_10792() { + struct One { + a: u32, + } + struct Two { + b: u32, + c: u64, + } + const ONE: One = One { a: 1 }; + const TWO: Two = Two { b: 2, c: 3 }; + let _ = 10 / ONE.a; + let _ = 10 / TWO.b; + let _ = 10 / TWO.c; +} + +pub fn issue_11145() { + let mut x: Wrapping = Wrapping(0_u32); + x += 1; +} + +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) fn main() {} diff --git a/tests/ui/arithmetic_side_effects.stderr b/tests/ui/arithmetic_side_effects.stderr index 2c8ee2884e73..f28ca496a67e 100644 --- a/tests/ui/arithmetic_side_effects.stderr +++ b/tests/ui/arithmetic_side_effects.stderr @@ -1,5 +1,38 @@ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:286:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:304:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:304:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:304:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:293:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:304:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:304:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:293:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:304:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n += 1; | ^^^^^^^ @@ -7,652 +40,4297 @@ LL | _n += 1; = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings` error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:287:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:305:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:305:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:305:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:294:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:305:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:305:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:294:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:305:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n += &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:288:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:306:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:306:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:306:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:295:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:306:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:306:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:295:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:306:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n -= 1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:289:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:307:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:307:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:307:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:296:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:307:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:307:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:296:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:307:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n -= &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:290:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:308:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:308:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:308:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:297:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:308:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:308:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:297:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:308:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n /= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:291:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:309:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:309:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:309:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:298:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:309:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:309:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:298:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:309:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n /= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:292:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:310:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:310:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:310:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:299:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:310:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:310:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:299:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:310:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n %= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:293:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:311:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:311:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:311:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:300:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:311:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:311:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:300:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:311:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n %= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:294:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:312:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:312:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:312:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:301:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:312:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:312:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:301:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:312:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n *= 2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:295:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:313:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:313:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:313:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:302:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:313:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:313:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:302:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:313:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n *= &2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:296:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:314:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:314:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:314:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:303:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:314:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:314:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:303:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:314:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n += -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:297:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:315:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:315:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:315:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:304:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:315:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:315:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:304:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:315:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n += &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:298:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:316:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:316:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:316:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:305:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:316:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:316:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:305:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:316:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n -= -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:299:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:317:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:317:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:317:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:306:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:317:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:317:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:306:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:317:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n -= &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:300:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:318:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:318:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:318:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:307:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:318:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:318:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:307:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:318:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n /= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:301:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:319:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:319:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:319:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:308:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:319:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:319:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:308:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:319:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n /= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:302:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:320:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:320:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:320:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:309:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:320:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:320:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:309:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:320:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n %= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:303:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:321:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:321:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:321:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:310:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:321:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:321:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:310:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:321:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n %= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:304:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:322:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:322:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:322:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:311:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:322:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:322:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:311:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:322:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n *= -2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:305:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:323:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:323:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:323:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:312:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:323:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:323:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:312:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:323:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n *= &-2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:306:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:324:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:324:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:324:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:313:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:324:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:324:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:313:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:324:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom += Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:307:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:325:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:325:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:325:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:314:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:325:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:325:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:314:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:325:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom += &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:308:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:326:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:326:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:326:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:315:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:326:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:326:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:315:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:326:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom -= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:309:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:327:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:327:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:327:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:316:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:327:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:327:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:316:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:327:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom -= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:310:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:328:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:328:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:328:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:317:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:328:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:328:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:317:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:328:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom /= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:311:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:329:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:329:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:329:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:318:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:329:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:329:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:318:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:329:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom /= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:312:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:330:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:330:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:330:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:319:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:330:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:330:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:319:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:330:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom %= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:313:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:331:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:331:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:331:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:320:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:331:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:331:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:320:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:331:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom %= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:314:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:332:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:332:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:332:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:321:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:332:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:332:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:321:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:332:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom *= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:315:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:333:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:333:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:333:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:322:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:333:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:333:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:322:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:333:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom *= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:316:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:334:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:334:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:334:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:323:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:334:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:334:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:323:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:334:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom >>= Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:317:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:335:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:335:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:335:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:324:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:335:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:335:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:324:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:335:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom >>= &Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:318:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:336:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:336:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:336:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:325:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:336:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:336:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:325:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:336:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom <<= Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:319:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:337:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:337:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:337:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:326:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:337:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:337:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:326:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:337:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom <<= &Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:320:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:338:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:338:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:338:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:327:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:338:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:338:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:327:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:338:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom += -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:321:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:339:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:339:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:339:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:328:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:339:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:339:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:328:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:339:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom += &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:322:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:340:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:340:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:340:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:329:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:340:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:340:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:329:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:340:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom -= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:323:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:341:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:341:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:341:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:330:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:341:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:341:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:330:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:341:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom -= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:324:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:342:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:342:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:342:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:331:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:342:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:342:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:331:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:342:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom /= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:325:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:343:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:343:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:343:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:332:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:343:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:343:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:332:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:343:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom /= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:326:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:344:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:344:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:344:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:333:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:344:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:344:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:333:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:344:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom %= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:327:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:345:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:345:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:345:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:334:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:345:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:345:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:334:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:345:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom %= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:328:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:346:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:346:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:346:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:335:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:346:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:346:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:335:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:346:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom *= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:329:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:347:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:347:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:347:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:336:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:347:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:347:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:336:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:347:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom *= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:330:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:348:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:348:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:348:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:337:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:348:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:348:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:337:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:348:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom >>= -Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:331:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:349:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:349:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:349:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:338:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:349:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:349:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:338:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:349:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom >>= &-Custom; | ^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:332:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:350:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:350:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:350:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:339:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:350:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:350:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:339:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:350:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom <<= -Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:333:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:351:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:351:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:351:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:340:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:351:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:351:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:340:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:351:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom <<= &-Custom; | ^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:336:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:354:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:354:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:354:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:343:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:354:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:354:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:343:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:354:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = _n + 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:337:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:355:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:355:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:355:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:344:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:355:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:355:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:344:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:355:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = _n + &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:338:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:356:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:356:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:356:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:345:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:356:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:356:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:345:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:356:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = 1 + _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:339:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:357:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:357:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:357:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:346:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:357:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:357:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:346:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:357:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = &1 + _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:340:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:358:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:358:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:358:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:347:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:358:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:358:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:347:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:358:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = _n - 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:341:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:359:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:359:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:359:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:348:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:359:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:359:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:348:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:359:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = _n - &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:342:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:360:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:360:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:360:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:349:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:360:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:360:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:349:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:360:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = 1 - _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:343:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:361:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:361:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:361:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:350:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:361:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:361:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:350:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:361:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = &1 - _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:344:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:362:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:362:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:362:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:351:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:362:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:362:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:351:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:362:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = _n / 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:345:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:363:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:363:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:363:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:352:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:363:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:363:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:352:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:363:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = _n / &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:346:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:364:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:364:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:364:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:353:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:364:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:364:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:353:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:364:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = _n % 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:347:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:365:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:365:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:365:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:354:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:365:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:365:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:354:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:365:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = _n % &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:348:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:366:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:366:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:366:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:355:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:366:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:366:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:355:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:366:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = _n * 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:349:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:367:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:367:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:367:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:356:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:367:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:367:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:356:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:367:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = _n * &2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:350:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:368:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:368:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:368:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:357:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:368:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:368:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:357:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:368:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = 2 * _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:351:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:369:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:369:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:369:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:358:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:369:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:369:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:358:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:369:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = &2 * _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:352:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:370:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:370:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:370:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:359:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:370:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:370:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:359:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:370:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = 23 + &85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:353:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:371:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:371:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:371:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:360:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:371:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:371:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:360:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:371:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = &23 + 85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:354:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:372:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:372:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:372:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:361:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:372:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:372:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:361:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:372:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = &23 + &85; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:355:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:373:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:373:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:373:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:362:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:373:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:373:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:362:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:373:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:356:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:374:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:374:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:374:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:363:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:374:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:374:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:363:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:374:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom + &_custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:357:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:375:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:375:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:375:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:364:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:375:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:375:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:364:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:375:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = Custom + _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:358:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:376:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:376:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:376:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:365:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:376:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:376:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:365:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:376:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = &Custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:359:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:377:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:377:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:377:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:366:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:377:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:377:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:366:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:377:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom - Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:360:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:378:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:378:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:378:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:367:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:378:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:378:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:367:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:378:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom - &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:361:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:379:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:379:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:379:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:368:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:379:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:379:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:368:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:379:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = Custom - _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:362:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:380:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:380:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:380:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:369:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:380:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:380:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:369:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:380:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = &Custom - _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:363:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:381:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:381:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:381:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:370:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:381:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:381:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:370:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:381:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom / Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:364:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:382:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:382:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:382:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:371:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:382:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:382:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:371:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:382:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom / &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:365:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:383:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:383:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:383:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:372:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:383:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:383:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:372:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:383:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom % Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:366:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:384:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:384:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:384:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:373:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:384:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:384:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:373:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:384:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom % &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:367:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:385:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:385:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:385:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:374:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:385:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:385:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:374:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:385:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom * Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:368:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:386:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:386:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:386:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:375:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:386:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:386:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:375:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:386:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom * &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:369:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:387:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:387:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:387:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:376:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:387:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:387:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:376:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:387:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = Custom * _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:370:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:388:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:388:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:388:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:377:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:388:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:388:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:377:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:388:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = &Custom * _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:371:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:389:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:389:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:389:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:378:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:389:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:389:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:378:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:389:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = Custom + &Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:372:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:390:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:390:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:390:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:379:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:390:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:390:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:379:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:390:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = &Custom + Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:373:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:391:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:391:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:391:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:380:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:391:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:391:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:380:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:391:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = &Custom + &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:374:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:392:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:392:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:392:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:381:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:392:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:392:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:381:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:392:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom >> _custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:375:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:393:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:393:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:393:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:382:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:393:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:393:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:382:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:393:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = _custom >> &_custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:376:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:394:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:394:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:394:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:383:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:394:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:394:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:383:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:394:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = Custom << _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:377:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:395:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:395:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:395:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:384:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:395:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:395:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:384:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:395:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = &Custom << _custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:380:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:398:23 + | +LL | _n.saturating_div(0); + | ^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:399:21 + | +LL | _n.wrapping_div(0); + | ^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:400:21 + | +LL | _n.wrapping_rem(0); + | ^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:401:28 + | +LL | _n.wrapping_rem_euclid(0); + | ^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:403:23 + | +LL | _n.saturating_div(_n); + | ^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:404:21 + | +LL | _n.wrapping_div(_n); + | ^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:405:21 + | +LL | _n.wrapping_rem(_n); + | ^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:406:28 + | +LL | _n.wrapping_rem_euclid(_n); + | ^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:409:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:387:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:387:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = -_n; | ^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:381:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:410:10 +======= +======= + --> $DIR/arithmetic_side_effects.rs:410:10 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:410:10 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:388:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:410:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:410:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:388:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:410:10 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _n = -&_n; | ^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:382:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:411:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:411:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:411:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:389:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:411:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:411:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:389:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:411:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = -_custom; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:383:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:412:15 +======= +======= + --> $DIR/arithmetic_side_effects.rs:412:15 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:412:15 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:390:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:412:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:412:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:390:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:412:15 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | _custom = -&_custom; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:392:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:421:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:421:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:421:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:399:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:421:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:421:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:399:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:421:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | 1 + i; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:393:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:422:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:422:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:422:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:400:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:422:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:422:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:400:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:422:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | i * 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:423:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:423:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:423:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:401:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:423:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= --> $DIR/arithmetic_side_effects.rs:394:5 +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:423:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:401:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:423:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | 1 % i / 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:424:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:424:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:424:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:402:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:424:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= --> $DIR/arithmetic_side_effects.rs:395:5 +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:424:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:402:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:424:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | i - 2 + 2 - i; | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:396:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:425:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:425:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:425:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:403:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:425:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:425:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:403:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:425:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | -i; | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:407:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:436:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:436:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:436:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:414:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:436:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:436:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:414:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:436:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | i += 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:408:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:437:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:437:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:437:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:415:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:437:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:437:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:415:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:437:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | i -= 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:409:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:438:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:438:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:438:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:416:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:438:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:438:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:416:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:438:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | i *= 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:411:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:440:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:440:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:440:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:418:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:440:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:440:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:418:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:440:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | i /= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:413:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:442:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:442:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:442:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:420:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:442:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:442:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:420:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:442:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | i /= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:414:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:443:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:443:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:443:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:421:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:443:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:443:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:421:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:443:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | i /= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:416:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:445:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:445:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:445:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:423:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:445:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:445:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:423:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:445:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | i %= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:418:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:447:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:447:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:447:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:425:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:447:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:447:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:425:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:447:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | i %= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:419:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:448:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:448:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:448:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:426:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:448:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= + --> $DIR/arithmetic_side_effects.rs:448:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:426:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:448:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | i %= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:458:5 +======= +======= + --> $DIR/arithmetic_side_effects.rs:458:5 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/arithmetic_side_effects.rs:458:5 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/arithmetic_side_effects.rs:436:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:458:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +<<<<<<< HEAD +======= --> $DIR/arithmetic_side_effects.rs:429:5 +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:458:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/arithmetic_side_effects.rs:436:5 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/arithmetic_side_effects.rs:458:5 +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | 10 / a | ^^^^^^ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 117 previous errors +======= error: aborting due to 109 previous errors +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +error: aborting due to 117 previous errors +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +error: aborting due to 117 previous errors +>>>>>>> 3db7352b8 ([arithmetic_side_effects] Fix #10590) diff --git a/tests/ui/as_conversions.rs b/tests/ui/as_conversions.rs index c50d4088b5eb..5a6b73a1bb52 100644 --- a/tests/ui/as_conversions.rs +++ b/tests/ui/as_conversions.rs @@ -1,10 +1,14 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::as_conversions)] -#![allow(clippy::borrow_as_ptr)] +#![allow(clippy::borrow_as_ptr, unused)] extern crate proc_macros; -use proc_macros::external; +use proc_macros::{external, with_span}; fn main() { let i = 0u32 as u64; @@ -13,3 +17,11 @@ fn main() { external!(0u32 as u64); } + +with_span!( + span + + fn coverting() { + let x = 0u32 as u64; + } +); diff --git a/tests/ui/as_ptr_cast_mut.rs b/tests/ui/as_ptr_cast_mut.rs index 0d1d9258433b..7d71947e4281 100644 --- a/tests/ui/as_ptr_cast_mut.rs +++ b/tests/ui/as_ptr_cast_mut.rs @@ -1,6 +1,6 @@ #![allow(unused)] #![warn(clippy::as_ptr_cast_mut)] -#![allow(clippy::wrong_self_convention)] +#![allow(clippy::wrong_self_convention, clippy::unnecessary_cast)] struct MutPtrWrapper(Vec); impl MutPtrWrapper { diff --git a/tests/ui/as_underscore.fixed b/tests/ui/as_underscore.fixed index 948f6d8e6b10..69af84a0eaec 100644 --- a/tests/ui/as_underscore.fixed +++ b/tests/ui/as_underscore.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::as_underscore)] diff --git a/tests/ui/as_underscore.rs b/tests/ui/as_underscore.rs index 97785ed08a8d..a8cfb81d9a3f 100644 --- a/tests/ui/as_underscore.rs +++ b/tests/ui/as_underscore.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::as_underscore)] diff --git a/tests/ui/asm_syntax.rs b/tests/ui/asm_syntax.rs index 0220bf3331f5..3289b7ecbb6e 100644 --- a/tests/ui/asm_syntax.rs +++ b/tests/ui/asm_syntax.rs @@ -1,5 +1,10 @@ -// only-x86_64 -// ignore-aarch64 +<<<<<<< HEAD +//@only-target-x86_64 +//@ignore-target-aarch64 +======= +//@only-x86_64 +//@ignore-aarch64 +>>>>>>> e4f5d83fa (Fixed formatting.) #[warn(clippy::inline_asm_x86_intel_syntax)] mod warn_intel { diff --git a/tests/ui/assertions_on_result_states.fixed b/tests/ui/assertions_on_result_states.fixed index 2bb755290c50..3152bd3cae1a 100644 --- a/tests/ui/assertions_on_result_states.fixed +++ b/tests/ui/assertions_on_result_states.fixed @@ -1,5 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::assertions_on_result_states)] +#![allow(clippy::unnecessary_literal_unwrap)] use std::result::Result; diff --git a/tests/ui/assertions_on_result_states.rs b/tests/ui/assertions_on_result_states.rs index d8a9bd2f1c45..42755e935aa4 100644 --- a/tests/ui/assertions_on_result_states.rs +++ b/tests/ui/assertions_on_result_states.rs @@ -1,5 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::assertions_on_result_states)] +#![allow(clippy::unnecessary_literal_unwrap)] use std::result::Result; diff --git a/tests/ui/assertions_on_result_states.stderr b/tests/ui/assertions_on_result_states.stderr index 298d63c9c34f..be581030cb67 100644 --- a/tests/ui/assertions_on_result_states.stderr +++ b/tests/ui/assertions_on_result_states.stderr @@ -1,5 +1,5 @@ error: called `assert!` with `Result::is_ok` - --> $DIR/assertions_on_result_states.rs:24:5 + --> $DIR/assertions_on_result_states.rs:25:5 | LL | assert!(r.is_ok()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()` @@ -7,37 +7,37 @@ LL | assert!(r.is_ok()); = note: `-D clippy::assertions-on-result-states` implied by `-D warnings` error: called `assert!` with `Result::is_ok` - --> $DIR/assertions_on_result_states.rs:42:5 + --> $DIR/assertions_on_result_states.rs:43:5 | LL | assert!(get_ok().is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok().unwrap()` error: called `assert!` with `Result::is_ok` - --> $DIR/assertions_on_result_states.rs:45:5 + --> $DIR/assertions_on_result_states.rs:46:5 | LL | assert!(get_ok_macro!().is_ok()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok_macro!().unwrap()` error: called `assert!` with `Result::is_ok` - --> $DIR/assertions_on_result_states.rs:58:5 + --> $DIR/assertions_on_result_states.rs:59:5 | LL | assert!(r.is_ok()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()` error: called `assert!` with `Result::is_ok` - --> $DIR/assertions_on_result_states.rs:64:9 + --> $DIR/assertions_on_result_states.rs:65:9 | LL | assert!(r.is_ok()); | ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()` error: called `assert!` with `Result::is_err` - --> $DIR/assertions_on_result_states.rs:72:5 + --> $DIR/assertions_on_result_states.rs:73:5 | LL | assert!(r.is_err()); | ^^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap_err()` error: called `assert!` with `Result::is_err` - --> $DIR/assertions_on_result_states.rs:82:5 + --> $DIR/assertions_on_result_states.rs:83:5 | LL | assert!(res.is_err()) | ^^^^^^^^^^^^^^^^^^^^^ help: replace with: `res.unwrap_err();` diff --git a/tests/ui/assign_ops.fixed b/tests/ui/assign_ops.fixed index da034b51cfdb..ef45e97d1de1 100644 --- a/tests/ui/assign_ops.fixed +++ b/tests/ui/assign_ops.fixed @@ -1,8 +1,8 @@ -// run-rustfix +//@run-rustfix use core::num::Wrapping; -#[allow(dead_code, unused_assignments)] +#[allow(dead_code, unused_assignments, clippy::useless_vec)] #[warn(clippy::assign_op_pattern)] fn main() { let mut a = 5; diff --git a/tests/ui/assign_ops.rs b/tests/ui/assign_ops.rs index 337bb02c8a61..ae87afc485ed 100644 --- a/tests/ui/assign_ops.rs +++ b/tests/ui/assign_ops.rs @@ -1,8 +1,8 @@ -// run-rustfix +//@run-rustfix use core::num::Wrapping; -#[allow(dead_code, unused_assignments)] +#[allow(dead_code, unused_assignments, clippy::useless_vec)] #[warn(clippy::assign_op_pattern)] fn main() { let mut a = 5; diff --git a/tests/ui/async_yields_async.fixed b/tests/ui/async_yields_async.fixed index 579a63ea4772..8d9b023893f7 100644 --- a/tests/ui/async_yields_async.fixed +++ b/tests/ui/async_yields_async.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] diff --git a/tests/ui/async_yields_async.rs b/tests/ui/async_yields_async.rs index 5aec2fb50f6a..bed79062f015 100644 --- a/tests/ui/async_yields_async.rs +++ b/tests/ui/async_yields_async.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] diff --git a/tests/ui/author/blocks.rs b/tests/ui/author/blocks.rs index a7335c01baa3..164f7d0d9d6c 100644 --- a/tests/ui/author/blocks.rs +++ b/tests/ui/author/blocks.rs @@ -1,4 +1,4 @@ -// edition:2018 +//@edition:2018 #![allow(redundant_semicolons, clippy::no_effect)] #![feature(stmt_expr_attributes)] diff --git a/tests/ui/auxiliary/extern_fake_libc.rs b/tests/ui/auxiliary/extern_fake_libc.rs new file mode 100644 index 000000000000..eb5a5d2b8368 --- /dev/null +++ b/tests/ui/auxiliary/extern_fake_libc.rs @@ -0,0 +1,10 @@ +#![allow(nonstandard_style)] +#![allow(clippy::missing_safety_doc, unused)] + +type pid_t = i32; +pub unsafe fn getpid() -> pid_t { + pid_t::from(0) +} +pub fn getpid_SAFE_TRUTH() -> pid_t { + unsafe { getpid() } +} diff --git a/tests/ui/auxiliary/macro_rules.rs b/tests/ui/auxiliary/macro_rules.rs index a9bb61451dca..6b164967a28e 100644 --- a/tests/ui/auxiliary/macro_rules.rs +++ b/tests/ui/auxiliary/macro_rules.rs @@ -1,7 +1,6 @@ #![allow(dead_code)] //! Used to test that certain lints don't trigger in imported external macros - #[macro_export] macro_rules! try_err { () => { @@ -21,6 +20,13 @@ macro_rules! string_add { }; } +#[macro_export] +macro_rules! string_lit_as_bytes { + ($s:literal) => { + const C: &[u8] = $s.as_bytes(); + }; +} + #[macro_export] macro_rules! mut_mut { () => { @@ -37,3 +43,10 @@ macro_rules! issue_10421 { b = a; }; } + +#[macro_export] +macro_rules! macro_with_panic { + () => { + panic!() + }; +} diff --git a/tests/ui/auxiliary/macro_use_helper.rs b/tests/ui/auxiliary/macro_use_helper.rs index 7ed8a28dbd93..f20df6f0f09e 100644 --- a/tests/ui/auxiliary/macro_use_helper.rs +++ b/tests/ui/auxiliary/macro_use_helper.rs @@ -1,3 +1,5 @@ +//@aux-build:macro_rules.rs + extern crate macro_rules; // STMT @@ -13,8 +15,7 @@ pub mod inner { // RE-EXPORT // this will stick in `inner` module - pub use macro_rules::mut_mut; - pub use macro_rules::try_err; + pub use macro_rules::{mut_mut, try_err}; pub mod nested { pub use macro_rules::string_add; diff --git a/tests/ui/auxiliary/proc_macro_attr.rs b/tests/ui/auxiliary/proc_macro_attr.rs index b498fece5132..7a2d7497b143 100644 --- a/tests/ui/auxiliary/proc_macro_attr.rs +++ b/tests/ui/auxiliary/proc_macro_attr.rs @@ -1,7 +1,10 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +<<<<<<< HEAD +======= +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(repr128, proc_macro_hygiene, proc_macro_quote, box_patterns)] #![allow(incomplete_features)] #![allow(clippy::useless_conversion, clippy::uninlined_format_args)] @@ -12,11 +15,11 @@ extern crate syn; use proc_macro::TokenStream; use quote::{quote, quote_spanned}; -use syn::parse_macro_input; use syn::spanned::Spanned; use syn::token::Star; use syn::{ - parse_quote, FnArg, ImplItem, ItemImpl, ItemTrait, Lifetime, Pat, PatIdent, PatType, Signature, TraitItem, Type, + parse_macro_input, parse_quote, FnArg, ImplItem, ItemImpl, ItemTrait, Lifetime, Pat, PatIdent, PatType, Signature, + TraitItem, Type, }; #[proc_macro_attribute] @@ -82,7 +85,7 @@ pub fn rename_my_lifetimes(_args: TokenStream, input: TokenStream) -> TokenStrea elided += 1; // HACK: Syn uses `Span` from the proc_macro2 crate, and does not seem to reexport it. - // In order to avoid adding the dependency, get a default span from a non-existent token. + // In order to avoid adding the dependency, get a default span from a nonexistent token. // A default span is needed to mark the code as coming from expansion. let span = Star::default().span(); diff --git a/tests/ui/auxiliary/proc_macro_derive.rs b/tests/ui/auxiliary/proc_macro_derive.rs index a89a06308d09..8ce4a6a48e09 100644 --- a/tests/ui/auxiliary/proc_macro_derive.rs +++ b/tests/ui/auxiliary/proc_macro_derive.rs @@ -1,7 +1,10 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +<<<<<<< HEAD +======= +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(repr128, proc_macro_quote)] #![allow(incomplete_features)] #![allow(clippy::field_reassign_with_default)] @@ -9,7 +12,7 @@ extern crate proc_macro; -use proc_macro::{quote, TokenStream}; +use proc_macro::{quote, Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; #[proc_macro_derive(DeriveSomething)] pub fn derive(_: TokenStream) -> TokenStream { @@ -86,3 +89,129 @@ pub fn extra_lifetime(_input: TokenStream) -> TokenStream { } ) } + +#[allow(unused)] +#[proc_macro_derive(ArithmeticDerive)] +pub fn arithmetic_derive(_: TokenStream) -> TokenStream { +<<<<<<< HEAD + >::from_iter([ + Ident::new("fn", Span::call_site()).into(), + Ident::new("_foo", Span::call_site()).into(), + Group::new(Delimiter::Parenthesis, TokenStream::new()).into(), + Group::new( + Delimiter::Brace, + >::from_iter([ + Ident::new("let", Span::call_site()).into(), + Ident::new("mut", Span::call_site()).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Literal::i32_unsuffixed(9).into(), + Punct::new(';', Spacing::Alone).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Literal::i32_unsuffixed(9).into(), + Punct::new('/', Spacing::Alone).into(), + Literal::i32_unsuffixed(2).into(), + Punct::new(';', Spacing::Alone).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Punct::new('-', Spacing::Alone).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new(';', Spacing::Alone).into(), + ]), + ) + .into(), + ]) +======= + >::from_iter( + [ + Ident::new("fn", Span::call_site()).into(), + Ident::new("_foo", Span::call_site()).into(), + Group::new(Delimiter::Parenthesis, TokenStream::new()).into(), + Group::new( + Delimiter::Brace, + >::from_iter( + [ + Ident::new("let", Span::call_site()).into(), + Ident::new("mut", Span::call_site()).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Literal::i32_unsuffixed(9).into(), + Punct::new(';', Spacing::Alone).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Literal::i32_unsuffixed(9).into(), + Punct::new('/', Spacing::Alone).into(), + Literal::i32_unsuffixed(2).into(), + Punct::new(';', Spacing::Alone).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Punct::new('-', Spacing::Alone).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new(';', Spacing::Alone).into(), + ] + .into_iter(), + ), + ) + .into(), + ] + .into_iter(), + ) +>>>>>>> e4f5d83fa (Fixed formatting.) +} + +#[allow(unused)] +#[proc_macro_derive(ShadowDerive)] +pub fn shadow_derive(_: TokenStream) -> TokenStream { +<<<<<<< HEAD + >::from_iter([ + Ident::new("fn", Span::call_site()).into(), + Ident::new("_foo", Span::call_site()).into(), + Group::new(Delimiter::Parenthesis, TokenStream::new()).into(), + Group::new( + Delimiter::Brace, + >::from_iter([ + Ident::new("let", Span::call_site()).into(), + Ident::new("_x", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Literal::i32_unsuffixed(2).into(), + Punct::new(';', Spacing::Alone).into(), + Ident::new("let", Span::call_site()).into(), + Ident::new("_x", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Ident::new("_x", Span::call_site()).into(), + Punct::new(';', Spacing::Alone).into(), + ]), + ) + .into(), + ]) +======= + >::from_iter( + [ + Ident::new("fn", Span::call_site()).into(), + Ident::new("_foo", Span::call_site()).into(), + Group::new(Delimiter::Parenthesis, TokenStream::new()).into(), + Group::new( + Delimiter::Brace, + >::from_iter( + [ + Ident::new("let", Span::call_site()).into(), + Ident::new("_x", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Literal::i32_unsuffixed(2).into(), + Punct::new(';', Spacing::Alone).into(), + Ident::new("let", Span::call_site()).into(), + Ident::new("_x", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Ident::new("_x", Span::call_site()).into(), + Punct::new(';', Spacing::Alone).into(), + ] + .into_iter(), + ), + ) + .into(), + ] + .into_iter(), + ) +>>>>>>> e4f5d83fa (Fixed formatting.) +} diff --git a/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs b/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs index a2ef0fe827c0..fe7247aff9b6 100644 --- a/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs +++ b/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs @@ -1,8 +1,11 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +<<<<<<< HEAD +======= +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] +>>>>>>> e4f5d83fa (Fixed formatting.) extern crate proc_macro; use proc_macro::{token_stream, Delimiter, Group, Ident, Span, TokenStream, TokenTree}; diff --git a/tests/ui/auxiliary/proc_macro_unsafe.rs b/tests/ui/auxiliary/proc_macro_unsafe.rs index 3c40f77469b8..595ff3df3dec 100644 --- a/tests/ui/auxiliary/proc_macro_unsafe.rs +++ b/tests/ui/auxiliary/proc_macro_unsafe.rs @@ -1,8 +1,11 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +<<<<<<< HEAD +======= +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] +>>>>>>> e4f5d83fa (Fixed formatting.) extern crate proc_macro; use proc_macro::{Delimiter, Group, Ident, TokenStream, TokenTree}; diff --git a/tests/ui/auxiliary/proc_macros.rs b/tests/ui/auxiliary/proc_macros.rs index 3d5beab1eff1..31862a9fe491 100644 --- a/tests/ui/auxiliary/proc_macros.rs +++ b/tests/ui/auxiliary/proc_macros.rs @@ -1,21 +1,21 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +<<<<<<< HEAD +======= +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(let_chains)] #![feature(proc_macro_span)] -#![allow(dead_code)] +#![allow(clippy::needless_if, dead_code)] extern crate proc_macro; use core::mem; -use proc_macro::{ - token_stream::IntoIter, - Delimiter::{self, Brace, Parenthesis}, - Group, Ident, Literal, Punct, - Spacing::{self, Alone, Joint}, - Span, TokenStream, TokenTree as TT, -}; +use proc_macro::token_stream::IntoIter; +use proc_macro::Delimiter::{self, Brace, Parenthesis}; +use proc_macro::Spacing::{self, Alone, Joint}; +use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree as TT}; type Result = core::result::Result; diff --git a/tests/ui/auxiliary/wildcard_imports_helper.rs b/tests/ui/auxiliary/wildcard_imports_helper.rs index d75cdd625f9e..44f49c080cdd 100644 --- a/tests/ui/auxiliary/wildcard_imports_helper.rs +++ b/tests/ui/auxiliary/wildcard_imports_helper.rs @@ -25,3 +25,9 @@ pub mod prelude { pub struct PreludeModAnywhere; } } + +pub mod extern_prelude { + pub mod v1 { + pub struct ExternPreludeModAnywhere; + } +} diff --git a/tests/ui/bind_instead_of_map.fixed b/tests/ui/bind_instead_of_map.fixed index d94e2ac6072d..ea2dc2e22932 100644 --- a/tests/ui/bind_instead_of_map.fixed +++ b/tests/ui/bind_instead_of_map.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::bind_instead_of_map)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/bind_instead_of_map.rs b/tests/ui/bind_instead_of_map.rs index 86f31f58284a..1db58dae5386 100644 --- a/tests/ui/bind_instead_of_map.rs +++ b/tests/ui/bind_instead_of_map.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::bind_instead_of_map)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/bind_instead_of_map.stderr b/tests/ui/bind_instead_of_map.stderr index b6a81d21bb20..f17fee7460dc 100644 --- a/tests/ui/bind_instead_of_map.stderr +++ b/tests/ui/bind_instead_of_map.stderr @@ -14,7 +14,7 @@ error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed --> $DIR/bind_instead_of_map.rs:10:13 | LL | let _ = x.and_then(|o| Some(o + 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `x.map(|o| o + 1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.map(|o| o + 1)` error: using `Result.and_then(Ok)`, which is a no-op --> $DIR/bind_instead_of_map.rs:16:13 diff --git a/tests/ui/bind_instead_of_map_multipart.fixed b/tests/ui/bind_instead_of_map_multipart.fixed index e1589843226c..63c7aafcddb2 100644 --- a/tests/ui/bind_instead_of_map_multipart.fixed +++ b/tests/ui/bind_instead_of_map_multipart.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::bind_instead_of_map)] #![allow(clippy::blocks_in_if_conditions)] diff --git a/tests/ui/bind_instead_of_map_multipart.rs b/tests/ui/bind_instead_of_map_multipart.rs index 49944403f6dd..69b982fa8a21 100644 --- a/tests/ui/bind_instead_of_map_multipart.rs +++ b/tests/ui/bind_instead_of_map_multipart.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::bind_instead_of_map)] #![allow(clippy::blocks_in_if_conditions)] diff --git a/tests/ui/bind_instead_of_map_multipart.stderr b/tests/ui/bind_instead_of_map_multipart.stderr index 0152a93feee4..cedbca785610 100644 --- a/tests/ui/bind_instead_of_map_multipart.stderr +++ b/tests/ui/bind_instead_of_map_multipart.stderr @@ -9,7 +9,7 @@ note: the lint level is defined here | LL | #![deny(clippy::bind_instead_of_map)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: try this +help: try | LL | let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); | ~~~ ~ ~~~~~~~ @@ -20,7 +20,7 @@ error: using `Result.and_then(|x| Ok(y))`, which is more succinctly expressed as LL | let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: try this +help: try | LL | let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() }); | ~~~ ~ ~~~~~~~ @@ -31,7 +31,7 @@ error: using `Result.or_else(|x| Err(y))`, which is more succinctly expressed as LL | let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: try this +help: try | LL | let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() }); | ~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~ @@ -48,7 +48,7 @@ LL | | } LL | | }); | |______^ | -help: try this +help: try | LL ~ Some("42").map(|s| { LL | if { @@ -82,7 +82,7 @@ error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed LL | let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: try this +help: try | LL | let _ = Some("").map(|s| if s.len() == 20 { m!() } else { Some(20) }); | ~~~ ~~~~ ~~~~~~~~ diff --git a/tests/ui/blanket_clippy_restriction_lints.rs b/tests/ui/blanket_clippy_restriction_lints.rs index 554745368bca..e1ff25c54cfc 100644 --- a/tests/ui/blanket_clippy_restriction_lints.rs +++ b/tests/ui/blanket_clippy_restriction_lints.rs @@ -1,4 +1,4 @@ -// compile-flags: -W clippy::restriction +//@compile-flags: -W clippy::restriction #![warn(clippy::blanket_clippy_restriction_lints)] diff --git a/tests/ui/blocks_in_if_conditions.fixed b/tests/ui/blocks_in_if_conditions.fixed index e6e40a9948c9..2a3867ac8fc0 100644 --- a/tests/ui/blocks_in_if_conditions.fixed +++ b/tests/ui/blocks_in_if_conditions.fixed @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::blocks_in_if_conditions)] -#![allow(unused, clippy::let_and_return)] +#![allow(unused, clippy::let_and_return, clippy::needless_if)] #![warn(clippy::nonminimal_bool)] macro_rules! blocky { diff --git a/tests/ui/blocks_in_if_conditions.rs b/tests/ui/blocks_in_if_conditions.rs index 69387ff5782b..704d09fbad3d 100644 --- a/tests/ui/blocks_in_if_conditions.rs +++ b/tests/ui/blocks_in_if_conditions.rs @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::blocks_in_if_conditions)] -#![allow(unused, clippy::let_and_return)] +#![allow(unused, clippy::let_and_return, clippy::needless_if)] #![warn(clippy::nonminimal_bool)] macro_rules! blocky { diff --git a/tests/ui/blocks_in_if_conditions_closure.rs b/tests/ui/blocks_in_if_conditions_closure.rs index 169589f6d4e7..9e27c9db2205 100644 --- a/tests/ui/blocks_in_if_conditions_closure.rs +++ b/tests/ui/blocks_in_if_conditions_closure.rs @@ -1,5 +1,20 @@ #![warn(clippy::blocks_in_if_conditions)] -#![allow(unused, clippy::let_and_return)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> bfd5abad4 (Fix all the other tests) +#![allow( + unused, + clippy::let_and_return, + clippy::needless_if, + clippy::unnecessary_literal_unwrap +)] +<<<<<<< HEAD +======= +#![allow(unused, clippy::let_and_return, clippy::needless_if)] +>>>>>>> 26f50395b (Add `needless_if` lint) +======= +>>>>>>> bfd5abad4 (Fix all the other tests) fn predicate bool, T>(pfn: F, val: T) -> bool { pfn(val) diff --git a/tests/ui/blocks_in_if_conditions_closure.stderr b/tests/ui/blocks_in_if_conditions_closure.stderr index 941d604dd5f9..5ac02e7504e8 100644 --- a/tests/ui/blocks_in_if_conditions_closure.stderr +++ b/tests/ui/blocks_in_if_conditions_closure.stderr @@ -1,5 +1,5 @@ error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - --> $DIR/blocks_in_if_conditions_closure.rs:18:17 + --> $DIR/blocks_in_if_conditions_closure.rs:23:17 | LL | |x| { | _________________^ @@ -11,7 +11,7 @@ LL | | }, = note: `-D clippy::blocks-in-if-conditions` implied by `-D warnings` error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - --> $DIR/blocks_in_if_conditions_closure.rs:27:13 + --> $DIR/blocks_in_if_conditions_closure.rs:32:13 | LL | |x| { | _____________^ diff --git a/tests/ui/bool_assert_comparison.fixed b/tests/ui/bool_assert_comparison.fixed index b8dd92906c8d..53f63444aefe 100644 --- a/tests/ui/bool_assert_comparison.fixed +++ b/tests/ui/bool_assert_comparison.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::assertions_on_constants)] #![warn(clippy::bool_assert_comparison)] diff --git a/tests/ui/bool_assert_comparison.rs b/tests/ui/bool_assert_comparison.rs index 0a8ad34fda52..151d93a9233b 100644 --- a/tests/ui/bool_assert_comparison.rs +++ b/tests/ui/bool_assert_comparison.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::assertions_on_constants)] #![warn(clippy::bool_assert_comparison)] diff --git a/tests/ui/bool_comparison.fixed b/tests/ui/bool_comparison.fixed index 5a012ff4d27a..8689f89d2c33 100644 --- a/tests/ui/bool_comparison.fixed +++ b/tests/ui/bool_comparison.fixed @@ -1,6 +1,8 @@ -// run-rustfix +//@run-rustfix +#![allow(clippy::needless_if)] #![warn(clippy::bool_comparison)] +#![allow(clippy::incorrect_partial_ord_impl_on_ord_type)] fn main() { let x = true; diff --git a/tests/ui/bool_comparison.rs b/tests/ui/bool_comparison.rs index c534bc25c20f..a1c94aff94b2 100644 --- a/tests/ui/bool_comparison.rs +++ b/tests/ui/bool_comparison.rs @@ -1,6 +1,8 @@ -// run-rustfix +//@run-rustfix +#![allow(clippy::needless_if)] #![warn(clippy::bool_comparison)] +#![allow(clippy::incorrect_partial_ord_impl_on_ord_type)] fn main() { let x = true; diff --git a/tests/ui/bool_comparison.stderr b/tests/ui/bool_comparison.stderr index 31522d4a5251..19bdf3013580 100644 --- a/tests/ui/bool_comparison.stderr +++ b/tests/ui/bool_comparison.stderr @@ -1,5 +1,5 @@ error: equality checks against true are unnecessary - --> $DIR/bool_comparison.rs:7:8 + --> $DIR/bool_comparison.rs:9:8 | LL | if x == true { | ^^^^^^^^^ help: try simplifying it as shown: `x` @@ -7,127 +7,127 @@ LL | if x == true { = note: `-D clippy::bool-comparison` implied by `-D warnings` error: equality checks against false can be replaced by a negation - --> $DIR/bool_comparison.rs:12:8 + --> $DIR/bool_comparison.rs:14:8 | LL | if x == false { | ^^^^^^^^^^ help: try simplifying it as shown: `!x` error: equality checks against true are unnecessary - --> $DIR/bool_comparison.rs:17:8 + --> $DIR/bool_comparison.rs:19:8 | LL | if true == x { | ^^^^^^^^^ help: try simplifying it as shown: `x` error: equality checks against false can be replaced by a negation - --> $DIR/bool_comparison.rs:22:8 + --> $DIR/bool_comparison.rs:24:8 | LL | if false == x { | ^^^^^^^^^^ help: try simplifying it as shown: `!x` error: inequality checks against true can be replaced by a negation - --> $DIR/bool_comparison.rs:27:8 + --> $DIR/bool_comparison.rs:29:8 | LL | if x != true { | ^^^^^^^^^ help: try simplifying it as shown: `!x` error: inequality checks against false are unnecessary - --> $DIR/bool_comparison.rs:32:8 + --> $DIR/bool_comparison.rs:34:8 | LL | if x != false { | ^^^^^^^^^^ help: try simplifying it as shown: `x` error: inequality checks against true can be replaced by a negation - --> $DIR/bool_comparison.rs:37:8 + --> $DIR/bool_comparison.rs:39:8 | LL | if true != x { | ^^^^^^^^^ help: try simplifying it as shown: `!x` error: inequality checks against false are unnecessary - --> $DIR/bool_comparison.rs:42:8 + --> $DIR/bool_comparison.rs:44:8 | LL | if false != x { | ^^^^^^^^^^ help: try simplifying it as shown: `x` error: less than comparison against true can be replaced by a negation - --> $DIR/bool_comparison.rs:47:8 + --> $DIR/bool_comparison.rs:49:8 | LL | if x < true { | ^^^^^^^^ help: try simplifying it as shown: `!x` error: greater than checks against false are unnecessary - --> $DIR/bool_comparison.rs:52:8 + --> $DIR/bool_comparison.rs:54:8 | LL | if false < x { | ^^^^^^^^^ help: try simplifying it as shown: `x` error: greater than checks against false are unnecessary - --> $DIR/bool_comparison.rs:57:8 + --> $DIR/bool_comparison.rs:59:8 | LL | if x > false { | ^^^^^^^^^ help: try simplifying it as shown: `x` error: less than comparison against true can be replaced by a negation - --> $DIR/bool_comparison.rs:62:8 + --> $DIR/bool_comparison.rs:64:8 | LL | if true > x { | ^^^^^^^^ help: try simplifying it as shown: `!x` error: order comparisons between booleans can be simplified - --> $DIR/bool_comparison.rs:68:8 + --> $DIR/bool_comparison.rs:70:8 | LL | if x < y { | ^^^^^ help: try simplifying it as shown: `!x & y` error: order comparisons between booleans can be simplified - --> $DIR/bool_comparison.rs:73:8 + --> $DIR/bool_comparison.rs:75:8 | LL | if x > y { | ^^^^^ help: try simplifying it as shown: `x & !y` error: this comparison might be written more concisely - --> $DIR/bool_comparison.rs:121:8 + --> $DIR/bool_comparison.rs:123:8 | LL | if a == !b {}; | ^^^^^^^ help: try simplifying it as shown: `a != b` error: this comparison might be written more concisely - --> $DIR/bool_comparison.rs:122:8 + --> $DIR/bool_comparison.rs:124:8 | LL | if !a == b {}; | ^^^^^^^ help: try simplifying it as shown: `a != b` error: this comparison might be written more concisely - --> $DIR/bool_comparison.rs:126:8 + --> $DIR/bool_comparison.rs:128:8 | LL | if b == !a {}; | ^^^^^^^ help: try simplifying it as shown: `b != a` error: this comparison might be written more concisely - --> $DIR/bool_comparison.rs:127:8 + --> $DIR/bool_comparison.rs:129:8 | LL | if !b == a {}; | ^^^^^^^ help: try simplifying it as shown: `b != a` error: equality checks against false can be replaced by a negation - --> $DIR/bool_comparison.rs:151:8 + --> $DIR/bool_comparison.rs:153:8 | LL | if false == m!(func) {} | ^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `!m!(func)` error: equality checks against false can be replaced by a negation - --> $DIR/bool_comparison.rs:152:8 + --> $DIR/bool_comparison.rs:154:8 | LL | if m!(func) == false {} | ^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `!m!(func)` error: equality checks against true are unnecessary - --> $DIR/bool_comparison.rs:153:8 + --> $DIR/bool_comparison.rs:155:8 | LL | if true == m!(func) {} | ^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `m!(func)` error: equality checks against true are unnecessary - --> $DIR/bool_comparison.rs:154:8 + --> $DIR/bool_comparison.rs:156:8 | LL | if m!(func) == true {} | ^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `m!(func)` diff --git a/tests/ui/bool_to_int_with_if.fixed b/tests/ui/bool_to_int_with_if.fixed index 37d3e3286a4b..fbb10a133e2b 100644 --- a/tests/ui/bool_to_int_with_if.fixed +++ b/tests/ui/bool_to_int_with_if.fixed @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix -#![feature(let_chains)] +#![feature(let_chains, inline_const)] #![warn(clippy::bool_to_int_with_if)] #![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)] @@ -79,6 +79,13 @@ fn main() { pub const SHOULD_NOT_LINT: usize = if true { 1 } else { 0 }; + // https://github.com/rust-lang/rust-clippy/issues/10452 + let should_not_lint = [(); if true { 1 } else { 0 }]; + + let should_not_lint = const { + if true { 1 } else { 0 } + }; + some_fn(a); } diff --git a/tests/ui/bool_to_int_with_if.rs b/tests/ui/bool_to_int_with_if.rs index ebdf86fd1856..709a18d63e40 100644 --- a/tests/ui/bool_to_int_with_if.rs +++ b/tests/ui/bool_to_int_with_if.rs @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix -#![feature(let_chains)] +#![feature(let_chains, inline_const)] #![warn(clippy::bool_to_int_with_if)] #![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)] @@ -111,6 +111,13 @@ fn main() { pub const SHOULD_NOT_LINT: usize = if true { 1 } else { 0 }; + // https://github.com/rust-lang/rust-clippy/issues/10452 + let should_not_lint = [(); if true { 1 } else { 0 }]; + + let should_not_lint = const { + if true { 1 } else { 0 } + }; + some_fn(a); } diff --git a/tests/ui/bool_to_int_with_if.stderr b/tests/ui/bool_to_int_with_if.stderr index 5cfb75cc0dfc..3bdae75cad22 100644 --- a/tests/ui/bool_to_int_with_if.stderr +++ b/tests/ui/bool_to_int_with_if.stderr @@ -98,7 +98,7 @@ LL | | }; = note: `!b as i32` or `(!b).into()` can also be valid options error: boolean to int conversion using if - --> $DIR/bool_to_int_with_if.rs:119:5 + --> $DIR/bool_to_int_with_if.rs:126:5 | LL | if a { 1 } else { 0 } | ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)` diff --git a/tests/ui/borrow_as_ptr.fixed b/tests/ui/borrow_as_ptr.fixed index ff5c6a8c3774..996cc3650ff0 100644 --- a/tests/ui/borrow_as_ptr.fixed +++ b/tests/ui/borrow_as_ptr.fixed @@ -1,9 +1,18 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::borrow_as_ptr)] +#![allow(clippy::useless_vec)] + +fn a() -> i32 { + 0 +} fn main() { let val = 1; let _p = std::ptr::addr_of!(val); + let _p = &0 as *const i32; + let _p = &a() as *const i32; + let vec = vec![1]; + let _p = &vec.len() as *const usize; let mut val_mut = 1; let _p_mut = std::ptr::addr_of_mut!(val_mut); diff --git a/tests/ui/borrow_as_ptr.rs b/tests/ui/borrow_as_ptr.rs index 0f62ec6ee58b..5eafaeb2fc30 100644 --- a/tests/ui/borrow_as_ptr.rs +++ b/tests/ui/borrow_as_ptr.rs @@ -1,9 +1,18 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::borrow_as_ptr)] +#![allow(clippy::useless_vec)] + +fn a() -> i32 { + 0 +} fn main() { let val = 1; let _p = &val as *const i32; + let _p = &0 as *const i32; + let _p = &a() as *const i32; + let vec = vec![1]; + let _p = &vec.len() as *const usize; let mut val_mut = 1; let _p_mut = &mut val_mut as *mut i32; diff --git a/tests/ui/borrow_as_ptr.stderr b/tests/ui/borrow_as_ptr.stderr index be1ed7330567..c9990bb6f226 100644 --- a/tests/ui/borrow_as_ptr.stderr +++ b/tests/ui/borrow_as_ptr.stderr @@ -1,5 +1,5 @@ error: borrow as raw pointer - --> $DIR/borrow_as_ptr.rs:6:14 + --> $DIR/borrow_as_ptr.rs:11:14 | LL | let _p = &val as *const i32; | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of!(val)` @@ -7,7 +7,7 @@ LL | let _p = &val as *const i32; = note: `-D clippy::borrow-as-ptr` implied by `-D warnings` error: borrow as raw pointer - --> $DIR/borrow_as_ptr.rs:9:18 + --> $DIR/borrow_as_ptr.rs:18:18 | LL | let _p_mut = &mut val_mut as *mut i32; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of_mut!(val_mut)` diff --git a/tests/ui/borrow_as_ptr_no_std.fixed b/tests/ui/borrow_as_ptr_no_std.fixed index eaba3b1c20c8..10f2727c793c 100644 --- a/tests/ui/borrow_as_ptr_no_std.fixed +++ b/tests/ui/borrow_as_ptr_no_std.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::borrow_as_ptr)] #![feature(lang_items, start, libc)] #![no_std] diff --git a/tests/ui/borrow_as_ptr_no_std.rs b/tests/ui/borrow_as_ptr_no_std.rs index d83f9d1f875b..311e9341aac2 100644 --- a/tests/ui/borrow_as_ptr_no_std.rs +++ b/tests/ui/borrow_as_ptr_no_std.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::borrow_as_ptr)] #![feature(lang_items, start, libc)] #![no_std] diff --git a/tests/ui/borrow_box.rs b/tests/ui/borrow_box.rs index 3b5b6bf4c950..95b6b0f50383 100644 --- a/tests/ui/borrow_box.rs +++ b/tests/ui/borrow_box.rs @@ -1,6 +1,10 @@ #![deny(clippy::borrowed_box)] #![allow(dead_code, unused_variables)] -#![allow(clippy::uninlined_format_args, clippy::disallowed_names)] +#![allow( + clippy::uninlined_format_args, + clippy::disallowed_names, + clippy::needless_pass_by_ref_mut +)] use std::fmt::Display; diff --git a/tests/ui/borrow_box.stderr b/tests/ui/borrow_box.stderr index 99cb60a1ead9..90e752211ff0 100644 --- a/tests/ui/borrow_box.stderr +++ b/tests/ui/borrow_box.stderr @@ -1,5 +1,5 @@ error: you seem to be trying to use `&Box`. Consider using just `&T` - --> $DIR/borrow_box.rs:20:14 + --> $DIR/borrow_box.rs:24:14 | LL | let foo: &Box; | ^^^^^^^^^^ help: try: `&bool` @@ -11,55 +11,55 @@ LL | #![deny(clippy::borrowed_box)] | ^^^^^^^^^^^^^^^^^^^^ error: you seem to be trying to use `&Box`. Consider using just `&T` - --> $DIR/borrow_box.rs:24:10 + --> $DIR/borrow_box.rs:28:10 | LL | foo: &'a Box, | ^^^^^^^^^^^^^ help: try: `&'a bool` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> $DIR/borrow_box.rs:28:17 + --> $DIR/borrow_box.rs:32:17 | LL | fn test4(a: &Box); | ^^^^^^^^^^ help: try: `&bool` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> $DIR/borrow_box.rs:94:25 + --> $DIR/borrow_box.rs:98:25 | LL | pub fn test14(_display: &Box) {} | ^^^^^^^^^^^^^^^^^ help: try: `&dyn Display` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> $DIR/borrow_box.rs:95:25 + --> $DIR/borrow_box.rs:99:25 | LL | pub fn test15(_display: &Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> $DIR/borrow_box.rs:96:29 + --> $DIR/borrow_box.rs:100:29 | LL | pub fn test16<'a>(_display: &'a Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (dyn Display + 'a)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> $DIR/borrow_box.rs:98:25 + --> $DIR/borrow_box.rs:102:25 | LL | pub fn test17(_display: &Box) {} | ^^^^^^^^^^^^^^^^^^ help: try: `&impl Display` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> $DIR/borrow_box.rs:99:25 + --> $DIR/borrow_box.rs:103:25 | LL | pub fn test18(_display: &Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(impl Display + Send)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> $DIR/borrow_box.rs:100:29 + --> $DIR/borrow_box.rs:104:29 | LL | pub fn test19<'a>(_display: &'a Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (impl Display + 'a)` error: you seem to be trying to use `&Box`. Consider using just `&T` - --> $DIR/borrow_box.rs:105:25 + --> $DIR/borrow_box.rs:109:25 | LL | pub fn test20(_display: &Box<(dyn Display + Send)>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)` diff --git a/tests/ui/borrow_deref_ref.fixed b/tests/ui/borrow_deref_ref.fixed index bf4691c5bc97..0bde3c34df9a 100644 --- a/tests/ui/borrow_deref_ref.fixed +++ b/tests/ui/borrow_deref_ref.fixed @@ -1,7 +1,32 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build: proc_macros.rs +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +//@aux-build: proc_macros.rs +>>>>>>> 394b4c190 (Ignore `borrow_deref_ref` warnings in code from procedural macros.) +======= +//@aux-build: proc_macros.rs:proc-macro +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) #![allow(dead_code, unused_variables)] +extern crate proc_macros; +use proc_macros::with_span; + fn main() {} mod should_lint { @@ -47,6 +72,17 @@ mod should_not_lint2 { } } +with_span!( + span + + fn just_returning(x: &u32) -> &u32 { + x + } + + fn dont_lint_proc_macro() { + let a = &mut &*just_returning(&12); + } +); // this mod explains why we should not lint `& &* (&T)` mod false_negative { fn foo() { diff --git a/tests/ui/borrow_deref_ref.rs b/tests/ui/borrow_deref_ref.rs index 28c005fdbef7..da10d1c77b86 100644 --- a/tests/ui/borrow_deref_ref.rs +++ b/tests/ui/borrow_deref_ref.rs @@ -1,7 +1,32 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build: proc_macros.rs +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +//@aux-build: proc_macros.rs +>>>>>>> 394b4c190 (Ignore `borrow_deref_ref` warnings in code from procedural macros.) +======= +//@aux-build: proc_macros.rs:proc-macro +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) #![allow(dead_code, unused_variables)] +extern crate proc_macros; +use proc_macros::with_span; + fn main() {} mod should_lint { @@ -47,6 +72,17 @@ mod should_not_lint2 { } } +with_span!( + span + + fn just_returning(x: &u32) -> &u32 { + x + } + + fn dont_lint_proc_macro() { + let a = &mut &*just_returning(&12); + } +); // this mod explains why we should not lint `& &* (&T)` mod false_negative { fn foo() { diff --git a/tests/ui/borrow_deref_ref.stderr b/tests/ui/borrow_deref_ref.stderr index d72de37c69ff..1e47cda67960 100644 --- a/tests/ui/borrow_deref_ref.stderr +++ b/tests/ui/borrow_deref_ref.stderr @@ -1,5 +1,5 @@ error: deref on an immutable reference - --> $DIR/borrow_deref_ref.rs:10:17 + --> $DIR/borrow_deref_ref.rs:14:17 | LL | let b = &*a; | ^^^ help: if you would like to reborrow, try removing `&*`: `a` @@ -7,13 +7,13 @@ LL | let b = &*a; = note: `-D clippy::borrow-deref-ref` implied by `-D warnings` error: deref on an immutable reference - --> $DIR/borrow_deref_ref.rs:12:22 + --> $DIR/borrow_deref_ref.rs:16:22 | LL | let b = &mut &*bar(&12); | ^^^^^^^^^^ help: if you would like to reborrow, try removing `&*`: `bar(&12)` error: deref on an immutable reference - --> $DIR/borrow_deref_ref.rs:55:23 + --> $DIR/borrow_deref_ref.rs:70:23 | LL | let addr_y = &&*x as *const _ as usize; // assert ok | ^^^ help: if you would like to reborrow, try removing `&*`: `x` diff --git a/tests/ui/borrow_interior_mutable_const/enums.rs b/tests/ui/borrow_interior_mutable_const/enums.rs index 5027db445617..da940a4cfb50 100644 --- a/tests/ui/borrow_interior_mutable_const/enums.rs +++ b/tests/ui/borrow_interior_mutable_const/enums.rs @@ -1,6 +1,6 @@ -// aux-build:helper.rs +//@aux-build:helper.rs -#![warn(clippy::borrow_interior_mutable_const)] +#![deny(clippy::borrow_interior_mutable_const)] #![allow(clippy::declare_interior_mutable_const)] // this file (mostly) replicates its `declare` counterpart. Please see it for more discussions. @@ -19,7 +19,7 @@ const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(true)); const FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen; fn borrow_optional_cell() { - let _ = &UNFROZEN_VARIANT; //~ ERROR interior mutability + let _ = &UNFROZEN_VARIANT; //~ ERROR: interior mutability let _ = &FROZEN_VARIANT; } @@ -34,11 +34,11 @@ trait AssocConsts { // This is the "suboptimal behavior" mentioned in `is_value_unfrozen` // caused by a similar reason to unfrozen types without any default values // get linted even if it has frozen variants'. - let _ = &Self::TO_BE_FROZEN_VARIANT; //~ ERROR interior mutable + let _ = &Self::TO_BE_FROZEN_VARIANT; //~ ERROR: interior mutability // The lint ignores default values because an impl of this trait can set // an unfrozen variant to `DEFAULTED_ON_FROZEN_VARIANT` and use the default impl for `function`. - let _ = &Self::DEFAULTED_ON_FROZEN_VARIANT; //~ ERROR interior mutable + let _ = &Self::DEFAULTED_ON_FROZEN_VARIANT; //~ ERROR: interior mutability } } @@ -47,9 +47,9 @@ impl AssocConsts for u64 { const TO_BE_FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen; fn function() { - let _ = &::TO_BE_UNFROZEN_VARIANT; //~ ERROR interior mutable + let _ = &::TO_BE_UNFROZEN_VARIANT; //~ ERROR: interior mutability let _ = &::TO_BE_FROZEN_VARIANT; - let _ = &Self::DEFAULTED_ON_UNFROZEN_VARIANT; //~ ERROR interior mutable + let _ = &Self::DEFAULTED_ON_UNFROZEN_VARIANT; //~ ERROR: interior mutability let _ = &Self::DEFAULTED_ON_FROZEN_VARIANT; } } @@ -67,11 +67,11 @@ trait AssocTypes { impl AssocTypes for u64 { type ToBeUnfrozen = AtomicUsize; - const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); //~ ERROR interior mutable + const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); const TO_BE_FROZEN_VARIANT: Option = None; fn function() { - let _ = &::TO_BE_UNFROZEN_VARIANT; //~ ERROR interior mutable + let _ = &::TO_BE_UNFROZEN_VARIANT; //~ ERROR: interior mutability let _ = &::TO_BE_FROZEN_VARIANT; } } @@ -83,19 +83,19 @@ enum BothOfCellAndGeneric { } impl BothOfCellAndGeneric { - const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); //~ ERROR interior mutable - const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR interior mutable + const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); + const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); const FROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Frozen(5); fn function() { - let _ = &Self::UNFROZEN_VARIANT; //~ ERROR interior mutability - let _ = &Self::GENERIC_VARIANT; //~ ERROR interior mutability + let _ = &Self::UNFROZEN_VARIANT; //~ ERROR: interior mutability + let _ = &Self::GENERIC_VARIANT; //~ ERROR: interior mutability let _ = &Self::FROZEN_VARIANT; } } fn main() { // constants defined in foreign crates - let _ = &helper::WRAPPED_PRIVATE_UNFROZEN_VARIANT; //~ ERROR interior mutability + let _ = &helper::WRAPPED_PRIVATE_UNFROZEN_VARIANT; //~ ERROR: interior mutability let _ = &helper::WRAPPED_PRIVATE_FROZEN_VARIANT; } diff --git a/tests/ui/borrow_interior_mutable_const/enums.stderr b/tests/ui/borrow_interior_mutable_const/enums.stderr index b0cab977a038..b753ec92608a 100644 --- a/tests/ui/borrow_interior_mutable_const/enums.stderr +++ b/tests/ui/borrow_interior_mutable_const/enums.stderr @@ -1,16 +1,20 @@ error: a `const` item with interior mutability should not be borrowed --> $DIR/enums.rs:22:14 | -LL | let _ = &UNFROZEN_VARIANT; //~ ERROR interior mutability +LL | let _ = &UNFROZEN_VARIANT; | ^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here - = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings` +note: the lint level is defined here + --> $DIR/enums.rs:3:9 + | +LL | #![deny(clippy::borrow_interior_mutable_const)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item with interior mutability should not be borrowed --> $DIR/enums.rs:37:18 | -LL | let _ = &Self::TO_BE_FROZEN_VARIANT; //~ ERROR interior mutable +LL | let _ = &Self::TO_BE_FROZEN_VARIANT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -18,7 +22,7 @@ LL | let _ = &Self::TO_BE_FROZEN_VARIANT; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/enums.rs:41:18 | -LL | let _ = &Self::DEFAULTED_ON_FROZEN_VARIANT; //~ ERROR interior mutable +LL | let _ = &Self::DEFAULTED_ON_FROZEN_VARIANT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -26,7 +30,7 @@ LL | let _ = &Self::DEFAULTED_ON_FROZEN_VARIANT; //~ ERROR interior muta error: a `const` item with interior mutability should not be borrowed --> $DIR/enums.rs:50:18 | -LL | let _ = &::TO_BE_UNFROZEN_VARIANT; //~ ERROR interior mutable +LL | let _ = &::TO_BE_UNFROZEN_VARIANT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -34,7 +38,7 @@ LL | let _ = &::TO_BE_UNFROZEN_VARIANT; //~ ERROR i error: a `const` item with interior mutability should not be borrowed --> $DIR/enums.rs:52:18 | -LL | let _ = &Self::DEFAULTED_ON_UNFROZEN_VARIANT; //~ ERROR interior mutable +LL | let _ = &Self::DEFAULTED_ON_UNFROZEN_VARIANT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -42,7 +46,7 @@ LL | let _ = &Self::DEFAULTED_ON_UNFROZEN_VARIANT; //~ ERROR interior mu error: a `const` item with interior mutability should not be borrowed --> $DIR/enums.rs:74:18 | -LL | let _ = &::TO_BE_UNFROZEN_VARIANT; //~ ERROR interior mutable +LL | let _ = &::TO_BE_UNFROZEN_VARIANT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -50,7 +54,7 @@ LL | let _ = &::TO_BE_UNFROZEN_VARIANT; //~ ERROR in error: a `const` item with interior mutability should not be borrowed --> $DIR/enums.rs:91:18 | -LL | let _ = &Self::UNFROZEN_VARIANT; //~ ERROR interior mutability +LL | let _ = &Self::UNFROZEN_VARIANT; | ^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -58,7 +62,7 @@ LL | let _ = &Self::UNFROZEN_VARIANT; //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/enums.rs:92:18 | -LL | let _ = &Self::GENERIC_VARIANT; //~ ERROR interior mutability +LL | let _ = &Self::GENERIC_VARIANT; | ^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -66,7 +70,7 @@ LL | let _ = &Self::GENERIC_VARIANT; //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/enums.rs:99:14 | -LL | let _ = &helper::WRAPPED_PRIVATE_UNFROZEN_VARIANT; //~ ERROR interior mutability +LL | let _ = &helper::WRAPPED_PRIVATE_UNFROZEN_VARIANT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here diff --git a/tests/ui/borrow_interior_mutable_const/others.rs b/tests/ui/borrow_interior_mutable_const/others.rs index 7c57864245a9..0ea93dd84625 100644 --- a/tests/ui/borrow_interior_mutable_const/others.rs +++ b/tests/ui/borrow_interior_mutable_const/others.rs @@ -1,4 +1,4 @@ -#![warn(clippy::borrow_interior_mutable_const)] +#![deny(clippy::borrow_interior_mutable_const)] #![allow(clippy::declare_interior_mutable_const, clippy::needless_borrow)] #![allow(const_item_mutation)] @@ -51,14 +51,14 @@ impl std::ops::Deref for StaticRef { const CELL_REF: StaticRef<(UnsafeCell,)> = unsafe { StaticRef::new(std::ptr::null()) }; fn main() { - ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability - assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability + ATOMIC.store(1, Ordering::SeqCst); //~ ERROR: interior mutability + assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR: interior mutability let _once = ONCE_INIT; - let _once_ref = &ONCE_INIT; //~ ERROR interior mutability - let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability - let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability - let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability + let _once_ref = &ONCE_INIT; //~ ERROR: interior mutability + let _once_ref_2 = &&ONCE_INIT; //~ ERROR: interior mutability + let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR: interior mutability + let _once_mut = &mut ONCE_INIT; //~ ERROR: interior mutability let _atomic_into_inner = ATOMIC.into_inner(); // these should be all fine. let _twice = (ONCE_INIT, ONCE_INIT); @@ -69,23 +69,23 @@ fn main() { let _ref_array_once = &[ONCE_INIT, ONCE_INIT][0]; // referencing projection is still bad. - let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability - let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability - let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability - let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability - let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mutability + let _ = &ATOMIC_TUPLE; //~ ERROR: interior mutability + let _ = &ATOMIC_TUPLE.0; //~ ERROR: interior mutability + let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR: interior mutability + let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR: interior mutability + let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR: interior mutability let _ = &*ATOMIC_TUPLE.1; let _ = &ATOMIC_TUPLE.2; let _ = (&&&&ATOMIC_TUPLE).0; let _ = (&&&&ATOMIC_TUPLE).2; let _ = ATOMIC_TUPLE.0; - let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability + let _ = ATOMIC_TUPLE.0[0]; //~ ERROR: interior mutability let _ = ATOMIC_TUPLE.1.into_iter(); let _ = ATOMIC_TUPLE.2; let _ = &{ ATOMIC_TUPLE }; - CELL.set(2); //~ ERROR interior mutability - assert_eq!(CELL.get(), 6); //~ ERROR interior mutability + CELL.set(2); //~ ERROR: interior mutability + assert_eq!(CELL.get(), 6); //~ ERROR: interior mutability assert_eq!(INTEGER, 8); assert!(STRING.is_empty()); diff --git a/tests/ui/borrow_interior_mutable_const/others.stderr b/tests/ui/borrow_interior_mutable_const/others.stderr index c87ad206c2ae..200e04b8f6be 100644 --- a/tests/ui/borrow_interior_mutable_const/others.stderr +++ b/tests/ui/borrow_interior_mutable_const/others.stderr @@ -1,16 +1,20 @@ error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:54:5 | -LL | ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability +LL | ATOMIC.store(1, Ordering::SeqCst); | ^^^^^^ | = help: assign this const to a local or static variable, and use the variable here - = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings` +note: the lint level is defined here + --> $DIR/others.rs:1:9 + | +LL | #![deny(clippy::borrow_interior_mutable_const)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:55:16 | -LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability +LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); | ^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -18,7 +22,7 @@ LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutabi error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:58:22 | -LL | let _once_ref = &ONCE_INIT; //~ ERROR interior mutability +LL | let _once_ref = &ONCE_INIT; | ^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -26,7 +30,7 @@ LL | let _once_ref = &ONCE_INIT; //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:59:25 | -LL | let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability +LL | let _once_ref_2 = &&ONCE_INIT; | ^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -34,7 +38,7 @@ LL | let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:60:27 | -LL | let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability +LL | let _once_ref_4 = &&&&ONCE_INIT; | ^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -42,7 +46,7 @@ LL | let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:61:26 | -LL | let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability +LL | let _once_mut = &mut ONCE_INIT; | ^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -50,7 +54,7 @@ LL | let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:72:14 | -LL | let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability +LL | let _ = &ATOMIC_TUPLE; | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -58,7 +62,7 @@ LL | let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:73:14 | -LL | let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability +LL | let _ = &ATOMIC_TUPLE.0; | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -66,7 +70,7 @@ LL | let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:74:19 | -LL | let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability +LL | let _ = &(&&&&ATOMIC_TUPLE).0; | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -74,7 +78,7 @@ LL | let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:75:14 | -LL | let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability +LL | let _ = &ATOMIC_TUPLE.0[0]; | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -82,7 +86,7 @@ LL | let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:76:13 | -LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mutability +LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -90,7 +94,7 @@ LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mu error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:82:13 | -LL | let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability +LL | let _ = ATOMIC_TUPLE.0[0]; | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -98,7 +102,7 @@ LL | let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:87:5 | -LL | CELL.set(2); //~ ERROR interior mutability +LL | CELL.set(2); | ^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -106,7 +110,7 @@ LL | CELL.set(2); //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:88:16 | -LL | assert_eq!(CELL.get(), 6); //~ ERROR interior mutability +LL | assert_eq!(CELL.get(), 6); | ^^^^ | = help: assign this const to a local or static variable, and use the variable here diff --git a/tests/ui/borrow_interior_mutable_const/traits.rs b/tests/ui/borrow_interior_mutable_const/traits.rs index 06b5d62e8f9a..4da3833cbf5a 100644 --- a/tests/ui/borrow_interior_mutable_const/traits.rs +++ b/tests/ui/borrow_interior_mutable_const/traits.rs @@ -1,4 +1,4 @@ -#![warn(clippy::borrow_interior_mutable_const)] +#![deny(clippy::borrow_interior_mutable_const)] #![allow(clippy::declare_interior_mutable_const)] // this file replicates its `declare` counterpart. Please see it for more discussions. @@ -12,7 +12,7 @@ trait ConcreteTypes { const STRING: String; fn function() { - let _ = &Self::ATOMIC; //~ ERROR interior mutable + let _ = &Self::ATOMIC; //~ ERROR: interior mutability let _ = &Self::STRING; } } @@ -23,7 +23,7 @@ impl ConcreteTypes for u64 { fn function() { // Lint this again since implementers can choose not to borrow it. - let _ = &Self::ATOMIC; //~ ERROR interior mutable + let _ = &Self::ATOMIC; //~ ERROR: interior mutability let _ = &Self::STRING; } } @@ -48,7 +48,7 @@ impl GenericTypes for Vec { fn function() { let _ = &Self::TO_REMAIN_GENERIC; - let _ = &Self::TO_BE_CONCRETE; //~ ERROR interior mutable + let _ = &Self::TO_BE_CONCRETE; //~ ERROR: interior mutability } } @@ -83,8 +83,8 @@ impl AssocTypes for Vec { fn function() { let _ = &Self::TO_BE_FROZEN; - let _ = &Self::TO_BE_UNFROZEN; //~ ERROR interior mutable - let _ = &Self::WRAPPED_TO_BE_UNFROZEN; //~ ERROR interior mutable + let _ = &Self::TO_BE_UNFROZEN; //~ ERROR: interior mutability + let _ = &Self::WRAPPED_TO_BE_UNFROZEN; //~ ERROR: interior mutability let _ = &Self::WRAPPED_TO_BE_GENERIC_PARAM; } } @@ -106,7 +106,7 @@ where fn function() { let _ = &Self::NOT_BOUNDED; - let _ = &Self::BOUNDED; //~ ERROR interior mutable + let _ = &Self::BOUNDED; //~ ERROR: interior mutability } } @@ -119,7 +119,7 @@ where fn function() { let _ = &Self::NOT_BOUNDED; - let _ = &Self::BOUNDED; //~ ERROR interior mutable + let _ = &Self::BOUNDED; //~ ERROR: interior mutability } } @@ -148,8 +148,8 @@ impl SelfType for AtomicUsize { const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); fn function() { - let _ = &Self::SELF; //~ ERROR interior mutable - let _ = &Self::WRAPPED_SELF; //~ ERROR interior mutable + let _ = &Self::SELF; //~ ERROR: interior mutability + let _ = &Self::WRAPPED_SELF; //~ ERROR: interior mutability } } @@ -159,7 +159,7 @@ trait BothOfCellAndGeneric { fn function() { let _ = &Self::DIRECT; - let _ = &Self::INDIRECT; //~ ERROR interior mutable + let _ = &Self::INDIRECT; //~ ERROR: interior mutability } } @@ -169,7 +169,7 @@ impl BothOfCellAndGeneric for Vec { fn function() { let _ = &Self::DIRECT; - let _ = &Self::INDIRECT; //~ ERROR interior mutable + let _ = &Self::INDIRECT; //~ ERROR: interior mutability } } @@ -188,15 +188,15 @@ where const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); fn function() { - let _ = &Self::ATOMIC; //~ ERROR interior mutable + let _ = &Self::ATOMIC; //~ ERROR: interior mutability let _ = &Self::COW; let _ = &Self::GENERIC_TYPE; let _ = &Self::ASSOC_TYPE; - let _ = &Self::BOUNDED_ASSOC_TYPE; //~ ERROR interior mutable + let _ = &Self::BOUNDED_ASSOC_TYPE; //~ ERROR: interior mutability } } fn main() { - u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability - assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability + u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR: interior mutability + assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR: interior mutability } diff --git a/tests/ui/borrow_interior_mutable_const/traits.stderr b/tests/ui/borrow_interior_mutable_const/traits.stderr index f34ae8814c33..add223acd68c 100644 --- a/tests/ui/borrow_interior_mutable_const/traits.stderr +++ b/tests/ui/borrow_interior_mutable_const/traits.stderr @@ -1,16 +1,20 @@ error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:15:18 | -LL | let _ = &Self::ATOMIC; //~ ERROR interior mutable +LL | let _ = &Self::ATOMIC; | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here - = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings` +note: the lint level is defined here + --> $DIR/traits.rs:1:9 + | +LL | #![deny(clippy::borrow_interior_mutable_const)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:26:18 | -LL | let _ = &Self::ATOMIC; //~ ERROR interior mutable +LL | let _ = &Self::ATOMIC; | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -18,7 +22,7 @@ LL | let _ = &Self::ATOMIC; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:51:18 | -LL | let _ = &Self::TO_BE_CONCRETE; //~ ERROR interior mutable +LL | let _ = &Self::TO_BE_CONCRETE; | ^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -26,7 +30,7 @@ LL | let _ = &Self::TO_BE_CONCRETE; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:86:18 | -LL | let _ = &Self::TO_BE_UNFROZEN; //~ ERROR interior mutable +LL | let _ = &Self::TO_BE_UNFROZEN; | ^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -34,7 +38,7 @@ LL | let _ = &Self::TO_BE_UNFROZEN; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:87:18 | -LL | let _ = &Self::WRAPPED_TO_BE_UNFROZEN; //~ ERROR interior mutable +LL | let _ = &Self::WRAPPED_TO_BE_UNFROZEN; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -42,7 +46,7 @@ LL | let _ = &Self::WRAPPED_TO_BE_UNFROZEN; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:109:18 | -LL | let _ = &Self::BOUNDED; //~ ERROR interior mutable +LL | let _ = &Self::BOUNDED; | ^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -50,7 +54,7 @@ LL | let _ = &Self::BOUNDED; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:122:18 | -LL | let _ = &Self::BOUNDED; //~ ERROR interior mutable +LL | let _ = &Self::BOUNDED; | ^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -58,7 +62,7 @@ LL | let _ = &Self::BOUNDED; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:151:18 | -LL | let _ = &Self::SELF; //~ ERROR interior mutable +LL | let _ = &Self::SELF; | ^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -66,7 +70,7 @@ LL | let _ = &Self::SELF; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:152:18 | -LL | let _ = &Self::WRAPPED_SELF; //~ ERROR interior mutable +LL | let _ = &Self::WRAPPED_SELF; | ^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -74,7 +78,7 @@ LL | let _ = &Self::WRAPPED_SELF; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:162:18 | -LL | let _ = &Self::INDIRECT; //~ ERROR interior mutable +LL | let _ = &Self::INDIRECT; | ^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -82,7 +86,7 @@ LL | let _ = &Self::INDIRECT; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:172:18 | -LL | let _ = &Self::INDIRECT; //~ ERROR interior mutable +LL | let _ = &Self::INDIRECT; | ^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -90,7 +94,7 @@ LL | let _ = &Self::INDIRECT; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:191:18 | -LL | let _ = &Self::ATOMIC; //~ ERROR interior mutable +LL | let _ = &Self::ATOMIC; | ^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -98,7 +102,7 @@ LL | let _ = &Self::ATOMIC; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:195:18 | -LL | let _ = &Self::BOUNDED_ASSOC_TYPE; //~ ERROR interior mutable +LL | let _ = &Self::BOUNDED_ASSOC_TYPE; | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -106,7 +110,7 @@ LL | let _ = &Self::BOUNDED_ASSOC_TYPE; //~ ERROR interior mutable error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:200:5 | -LL | u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability +LL | u64::ATOMIC.store(5, Ordering::SeqCst); | ^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here @@ -114,7 +118,7 @@ LL | u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:201:16 | -LL | assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability +LL | assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); | ^^^^^^^^^^^ | = help: assign this const to a local or static variable, and use the variable here diff --git a/tests/ui/box_default.fixed b/tests/ui/box_default.fixed index 59c0baf8718a..3ca541e0f8d0 100644 --- a/tests/ui/box_default.fixed +++ b/tests/ui/box_default.fixed @@ -1,5 +1,10 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::box_default)] +<<<<<<< HEAD +#![allow(unused, clippy::default_constructed_unit_structs)] +======= +#![allow(clippy::default_constructed_unit_structs)] +>>>>>>> e4f5d83fa (Fixed formatting.) #[derive(Default)] struct ImplementsDefault; @@ -34,6 +39,13 @@ fn main() { let _more = ret_ty_fn(); call_ty_fn(Box::default()); issue_10381(); + + // `Box::>::default()` would be valid here, but not `Box::default()` or + // `Box::::default()` + // + // Would have a suggestion after https://github.com/rust-lang/rust/blob/fdd030127cc68afec44a8d3f6341525dd34e50ae/compiler/rustc_middle/src/ty/diagnostics.rs#L554-L563 + let mut unnameable = Box::new(Option::default()); + let _ = unnameable.insert(|| {}); } fn ret_ty_fn() -> Box { diff --git a/tests/ui/box_default.rs b/tests/ui/box_default.rs index f7d832193a3a..3b1e40a3435e 100644 --- a/tests/ui/box_default.rs +++ b/tests/ui/box_default.rs @@ -1,5 +1,10 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::box_default)] +<<<<<<< HEAD +#![allow(unused, clippy::default_constructed_unit_structs)] +======= +#![allow(clippy::default_constructed_unit_structs)] +>>>>>>> e4f5d83fa (Fixed formatting.) #[derive(Default)] struct ImplementsDefault; @@ -34,6 +39,13 @@ fn main() { let _more = ret_ty_fn(); call_ty_fn(Box::new(u8::default())); issue_10381(); + + // `Box::>::default()` would be valid here, but not `Box::default()` or + // `Box::::default()` + // + // Would have a suggestion after https://github.com/rust-lang/rust/blob/fdd030127cc68afec44a8d3f6341525dd34e50ae/compiler/rustc_middle/src/ty/diagnostics.rs#L554-L563 + let mut unnameable = Box::new(Option::default()); + let _ = unnameable.insert(|| {}); } fn ret_ty_fn() -> Box { diff --git a/tests/ui/box_default.stderr b/tests/ui/box_default.stderr index 78e17b9f0359..550296204471 100644 --- a/tests/ui/box_default.stderr +++ b/tests/ui/box_default.stderr @@ -1,5 +1,5 @@ error: `Box::new(_)` of default value - --> $DIR/box_default.rs:22:32 + --> $DIR/box_default.rs:23:32 | LL | let _string: Box = Box::new(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` @@ -7,91 +7,107 @@ LL | let _string: Box = Box::new(Default::default()); = note: `-D clippy::box-default` implied by `-D warnings` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:23:17 + --> $DIR/box_default.rs:24:17 | LL | let _byte = Box::new(u8::default()); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:24:16 + --> $DIR/box_default.rs:25:16 | LL | let _vec = Box::new(Vec::::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:25:17 + --> $DIR/box_default.rs:26:17 | LL | let _impl = Box::new(ImplementsDefault::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:26:18 + --> $DIR/box_default.rs:27:18 | LL | let _impl2 = Box::new(::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:27:42 + --> $DIR/box_default.rs:28:42 | LL | let _impl3: Box = Box::new(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:29:28 + --> $DIR/box_default.rs:30:28 | LL | let _in_macro = outer!(Box::new(String::new())); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:30:34 + --> $DIR/box_default.rs:31:34 | LL | let _string_default = outer!(Box::new(String::from(""))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:31:46 + --> $DIR/box_default.rs:32:46 | LL | let _vec2: Box> = Box::new(vec![]); | ^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:32:33 + --> $DIR/box_default.rs:33:33 | LL | let _vec3: Box> = Box::new(Vec::from([])); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:33:25 + --> $DIR/box_default.rs:34:25 | LL | let _vec4: Box<_> = Box::new(Vec::from([false; 0])); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::>::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:35:16 + --> $DIR/box_default.rs:36:16 | LL | call_ty_fn(Box::new(u8::default())); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:40:5 +<<<<<<< HEAD + --> $DIR/box_default.rs:48:5 +======= + --> $DIR/box_default.rs:41:5 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | Box::new(bool::default()) | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:57:28 +<<<<<<< HEAD + --> $DIR/box_default.rs:65:28 +======= + --> $DIR/box_default.rs:58:28 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | let _: Box = Box::new(ImplementsDefault::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:66:17 +<<<<<<< HEAD + --> $DIR/box_default.rs:74:17 +======= + --> $DIR/box_default.rs:67:17 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | let _ = Box::new(WeirdPathed::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` error: `Box::new(_)` of default value - --> $DIR/box_default.rs:78:18 +<<<<<<< HEAD + --> $DIR/box_default.rs:86:18 +======= + --> $DIR/box_default.rs:79:18 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | Some(Box::new(Foo::default())) | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::::default()` diff --git a/tests/ui/branches_sharing_code/valid_if_blocks.rs b/tests/ui/branches_sharing_code/valid_if_blocks.rs index 2d6055eb6c42..5780ea089377 100644 --- a/tests/ui/branches_sharing_code/valid_if_blocks.rs +++ b/tests/ui/branches_sharing_code/valid_if_blocks.rs @@ -1,6 +1,10 @@ #![deny(clippy::branches_sharing_code, clippy::if_same_then_else)] #![allow(dead_code)] -#![allow(clippy::mixed_read_write_in_expression, clippy::uninlined_format_args)] +#![allow( + clippy::mixed_read_write_in_expression, + clippy::uninlined_format_args, + clippy::needless_else +)] // This tests valid if blocks that shouldn't trigger the lint diff --git a/tests/ui/branches_sharing_code/valid_if_blocks.stderr b/tests/ui/branches_sharing_code/valid_if_blocks.stderr index ce7fff0122f1..a7e72b780aff 100644 --- a/tests/ui/branches_sharing_code/valid_if_blocks.stderr +++ b/tests/ui/branches_sharing_code/valid_if_blocks.stderr @@ -1,5 +1,5 @@ error: this `if` has identical blocks - --> $DIR/valid_if_blocks.rs:105:14 + --> $DIR/valid_if_blocks.rs:109:14 | LL | if false { | ______________^ @@ -7,7 +7,7 @@ LL | | } else { | |_____^ | note: same as this - --> $DIR/valid_if_blocks.rs:106:12 + --> $DIR/valid_if_blocks.rs:110:12 | LL | } else { | ____________^ @@ -20,7 +20,7 @@ LL | #![deny(clippy::branches_sharing_code, clippy::if_same_then_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `if` has identical blocks - --> $DIR/valid_if_blocks.rs:116:15 + --> $DIR/valid_if_blocks.rs:120:15 | LL | if x == 0 { | _______________^ @@ -31,7 +31,7 @@ LL | | } else { | |_____^ | note: same as this - --> $DIR/valid_if_blocks.rs:120:12 + --> $DIR/valid_if_blocks.rs:124:12 | LL | } else { | ____________^ @@ -42,19 +42,19 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> $DIR/valid_if_blocks.rs:127:23 + --> $DIR/valid_if_blocks.rs:131:23 | LL | let _ = if x == 6 { 7 } else { 7 }; | ^^^^^ | note: same as this - --> $DIR/valid_if_blocks.rs:127:34 + --> $DIR/valid_if_blocks.rs:131:34 | LL | let _ = if x == 6 { 7 } else { 7 }; | ^^^^^ error: this `if` has identical blocks - --> $DIR/valid_if_blocks.rs:133:23 + --> $DIR/valid_if_blocks.rs:137:23 | LL | } else if x == 68 { | _______________________^ @@ -66,7 +66,7 @@ LL | | } else { | |_____^ | note: same as this - --> $DIR/valid_if_blocks.rs:138:12 + --> $DIR/valid_if_blocks.rs:142:12 | LL | } else { | ____________^ @@ -78,7 +78,7 @@ LL | | }; | |_____^ error: this `if` has identical blocks - --> $DIR/valid_if_blocks.rs:147:23 + --> $DIR/valid_if_blocks.rs:151:23 | LL | } else if x == 68 { | _______________________^ @@ -88,7 +88,7 @@ LL | | } else { | |_____^ | note: same as this - --> $DIR/valid_if_blocks.rs:150:12 + --> $DIR/valid_if_blocks.rs:154:12 | LL | } else { | ____________^ diff --git a/tests/ui/builtin_type_shadow.rs b/tests/ui/builtin_type_shadow.rs index 69b8b6a0e68c..c5addd53434c 100644 --- a/tests/ui/builtin_type_shadow.rs +++ b/tests/ui/builtin_type_shadow.rs @@ -3,7 +3,7 @@ fn foo(a: u32) -> u32 { 42 - // ^ rustc's type error + //~^ ERROR: mismatched types } fn main() {} diff --git a/tests/ui/bytecount.rs b/tests/ui/bytecount.rs index d3ad26921bff..4d168bfeab93 100644 --- a/tests/ui/bytecount.rs +++ b/tests/ui/bytecount.rs @@ -1,4 +1,4 @@ -#![allow(clippy::needless_borrow)] +#![allow(clippy::needless_borrow, clippy::useless_vec)] #[deny(clippy::naive_bytecount)] fn main() { diff --git a/tests/ui/bytes_count_to_len.fixed b/tests/ui/bytes_count_to_len.fixed index 860642363b5f..fb3d521badd5 100644 --- a/tests/ui/bytes_count_to_len.fixed +++ b/tests/ui/bytes_count_to_len.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::bytes_count_to_len)] use std::fs::File; use std::io::Read; diff --git a/tests/ui/bytes_count_to_len.rs b/tests/ui/bytes_count_to_len.rs index 162730c2842a..8e256b8f0b8a 100644 --- a/tests/ui/bytes_count_to_len.rs +++ b/tests/ui/bytes_count_to_len.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::bytes_count_to_len)] use std::fs::File; use std::io::Read; diff --git a/tests/ui/bytes_nth.fixed b/tests/ui/bytes_nth.fixed index a35c679afb71..d3e0f676b29f 100644 --- a/tests/ui/bytes_nth.fixed +++ b/tests/ui/bytes_nth.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::unnecessary_operation)] #![warn(clippy::bytes_nth)] diff --git a/tests/ui/bytes_nth.rs b/tests/ui/bytes_nth.rs index 1ecffea53035..b7d813fe296a 100644 --- a/tests/ui/bytes_nth.rs +++ b/tests/ui/bytes_nth.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::unnecessary_operation)] #![warn(clippy::bytes_nth)] diff --git a/tests/ui/case_sensitive_file_extension_comparisons.fixed b/tests/ui/case_sensitive_file_extension_comparisons.fixed index 5fbaa64db39e..d5af22aefe5d 100644 --- a/tests/ui/case_sensitive_file_extension_comparisons.fixed +++ b/tests/ui/case_sensitive_file_extension_comparisons.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::case_sensitive_file_extension_comparisons)] use std::string::String; diff --git a/tests/ui/case_sensitive_file_extension_comparisons.rs b/tests/ui/case_sensitive_file_extension_comparisons.rs index 3c0d4821f9f3..f5f0a0022a42 100644 --- a/tests/ui/case_sensitive_file_extension_comparisons.rs +++ b/tests/ui/case_sensitive_file_extension_comparisons.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::case_sensitive_file_extension_comparisons)] use std::string::String; diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs index a86b85706a34..60a0eabf55b0 100644 --- a/tests/ui/cast.rs +++ b/tests/ui/cast.rs @@ -41,6 +41,14 @@ fn main() { 1u32 as i32; 1u64 as i64; 1usize as isize; + 1usize as i8; // should not wrap, usize is never 8 bits + 1usize as i16; // wraps on 16 bit ptr size + 1usize as i32; // wraps on 32 bit ptr size + 1usize as i64; // wraps on 64 bit ptr size + 1u8 as isize; // should not wrap, isize is never 8 bits + 1u16 as isize; // wraps on 16 bit ptr size + 1u32 as isize; // wraps on 32 bit ptr size + 1u64 as isize; // wraps on 64 bit ptr size // Test clippy::cast_sign_loss 1i32 as u32; -1i32 as u32; diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 65ecf1aa37aa..4c62263364ce 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -215,20 +215,128 @@ error: casting `usize` to `isize` may wrap around the value LL | 1usize as isize; | ^^^^^^^^^^^^^^^ -error: casting `i32` to `u32` may lose the sign of the value +error: casting `usize` to `i8` may truncate the value + --> $DIR/cast.rs:44:5 + | +LL | 1usize as i8; // should not wrap, usize is never 8 bits + | ^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | i8::try_from(1usize); // should not wrap, usize is never 8 bits + | ~~~~~~~~~~~~~~~~~~~~ + +error: casting `usize` to `i16` may truncate the value + --> $DIR/cast.rs:45:5 + | +LL | 1usize as i16; // wraps on 16 bit ptr size + | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | i16::try_from(1usize); // wraps on 16 bit ptr size + | ~~~~~~~~~~~~~~~~~~~~~ + +error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers + --> $DIR/cast.rs:45:5 + | +LL | 1usize as i16; // wraps on 16 bit ptr size + | ^^^^^^^^^^^^^ +<<<<<<< HEAD +<<<<<<< HEAD + | + = note: `usize` and `isize` may be as small as 16 bits on some platforms + = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types +======= +>>>>>>> 6681914b5 (make cast_possible_wrap not lint on conversions for sizes that cannot wrap, and make it work correctly for 16 bit {u,i}size) +======= + | + = note: `usize` and `isize` may be as small as 16 bits on some platforms + = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types +>>>>>>> 7cd0ec58a (add more info link) + +error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers --> $DIR/cast.rs:46:5 | +LL | 1usize as i32; // wraps on 32 bit ptr size + | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | i32::try_from(1usize); // wraps on 32 bit ptr size + | ~~~~~~~~~~~~~~~~~~~~~ + +error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers + --> $DIR/cast.rs:46:5 + | +LL | 1usize as i32; // wraps on 32 bit ptr size + | ^^^^^^^^^^^^^ + +error: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers + --> $DIR/cast.rs:47:5 + | +LL | 1usize as i64; // wraps on 64 bit ptr size + | ^^^^^^^^^^^^^ + +error: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers + --> $DIR/cast.rs:49:5 + | +LL | 1u16 as isize; // wraps on 16 bit ptr size + | ^^^^^^^^^^^^^ +<<<<<<< HEAD +<<<<<<< HEAD + | + = note: `usize` and `isize` may be as small as 16 bits on some platforms + = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types +======= +>>>>>>> 6681914b5 (make cast_possible_wrap not lint on conversions for sizes that cannot wrap, and make it work correctly for 16 bit {u,i}size) +======= + | + = note: `usize` and `isize` may be as small as 16 bits on some platforms + = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types +>>>>>>> 7cd0ec58a (add more info link) + +error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers + --> $DIR/cast.rs:50:5 + | +LL | 1u32 as isize; // wraps on 32 bit ptr size + | ^^^^^^^^^^^^^ + +error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers + --> $DIR/cast.rs:51:5 + | +LL | 1u64 as isize; // wraps on 64 bit ptr size + | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | isize::try_from(1u64); // wraps on 64 bit ptr size + | ~~~~~~~~~~~~~~~~~~~~~ + +error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers + --> $DIR/cast.rs:51:5 + | +LL | 1u64 as isize; // wraps on 64 bit ptr size + | ^^^^^^^^^^^^^ + +error: casting `i32` to `u32` may lose the sign of the value + --> $DIR/cast.rs:54:5 + | LL | -1i32 as u32; | ^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> $DIR/cast.rs:48:5 + --> $DIR/cast.rs:56:5 | LL | -1isize as usize; | ^^^^^^^^^^^^^^^^ error: casting `i64` to `i8` may truncate the value - --> $DIR/cast.rs:115:5 + --> $DIR/cast.rs:123:5 | LL | (-99999999999i64).min(1) as i8; // should be linted because signed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -240,7 +348,7 @@ LL | i8::try_from((-99999999999i64).min(1)); // should be linted because sig | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> $DIR/cast.rs:127:5 + --> $DIR/cast.rs:135:5 | LL | 999999u64.clamp(0, 256) as u8; // should still be linted | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -252,7 +360,7 @@ LL | u8::try_from(999999u64.clamp(0, 256)); // should still be linted | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E2` to `u8` may truncate the value - --> $DIR/cast.rs:148:21 + --> $DIR/cast.rs:156:21 | LL | let _ = self as u8; | ^^^^^^^^^^ @@ -264,7 +372,7 @@ LL | let _ = u8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E2::B` to `u8` will truncate the value - --> $DIR/cast.rs:149:21 + --> $DIR/cast.rs:157:21 | LL | let _ = Self::B as u8; | ^^^^^^^^^^^^^ @@ -272,7 +380,7 @@ LL | let _ = Self::B as u8; = note: `-D clippy::cast-enum-truncation` implied by `-D warnings` error: casting `main::E5` to `i8` may truncate the value - --> $DIR/cast.rs:185:21 + --> $DIR/cast.rs:193:21 | LL | let _ = self as i8; | ^^^^^^^^^^ @@ -284,13 +392,13 @@ LL | let _ = i8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E5::A` to `i8` will truncate the value - --> $DIR/cast.rs:186:21 + --> $DIR/cast.rs:194:21 | LL | let _ = Self::A as i8; | ^^^^^^^^^^^^^ error: casting `main::E6` to `i16` may truncate the value - --> $DIR/cast.rs:200:21 + --> $DIR/cast.rs:208:21 | LL | let _ = self as i16; | ^^^^^^^^^^^ @@ -302,7 +410,7 @@ LL | let _ = i16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers - --> $DIR/cast.rs:215:21 + --> $DIR/cast.rs:223:21 | LL | let _ = self as usize; | ^^^^^^^^^^^^^ @@ -314,7 +422,7 @@ LL | let _ = usize::try_from(self); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E10` to `u16` may truncate the value - --> $DIR/cast.rs:256:21 + --> $DIR/cast.rs:264:21 | LL | let _ = self as u16; | ^^^^^^^^^^^ @@ -326,7 +434,7 @@ LL | let _ = u16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> $DIR/cast.rs:264:13 + --> $DIR/cast.rs:272:13 | LL | let c = (q >> 16) as u8; | ^^^^^^^^^^^^^^^ @@ -338,7 +446,7 @@ LL | let c = u8::try_from(q >> 16); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> $DIR/cast.rs:267:13 + --> $DIR/cast.rs:275:13 | LL | let c = (q / 1000) as u8; | ^^^^^^^^^^^^^^^^ @@ -349,5 +457,5 @@ help: ... or use `try_from` and handle the error accordingly LL | let c = u8::try_from(q / 1000); | ~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 41 previous errors +error: aborting due to 51 previous errors diff --git a/tests/ui/cast_abs_to_unsigned.fixed b/tests/ui/cast_abs_to_unsigned.fixed index 8676b562b4f9..ef0a93b01d1f 100644 --- a/tests/ui/cast_abs_to_unsigned.fixed +++ b/tests/ui/cast_abs_to_unsigned.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cast_abs_to_unsigned)] #![allow(clippy::uninlined_format_args, unused)] diff --git a/tests/ui/cast_abs_to_unsigned.rs b/tests/ui/cast_abs_to_unsigned.rs index 5775af874f8f..96ced670a055 100644 --- a/tests/ui/cast_abs_to_unsigned.rs +++ b/tests/ui/cast_abs_to_unsigned.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cast_abs_to_unsigned)] #![allow(clippy::uninlined_format_args, unused)] diff --git a/tests/ui/cast_lossless_bool.fixed b/tests/ui/cast_lossless_bool.fixed index 13b3cf838c9f..c321cc644378 100644 --- a/tests/ui/cast_lossless_bool.fixed +++ b/tests/ui/cast_lossless_bool.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::cast_lossless)] diff --git a/tests/ui/cast_lossless_bool.rs b/tests/ui/cast_lossless_bool.rs index 3eed2135562c..632a718920d4 100644 --- a/tests/ui/cast_lossless_bool.rs +++ b/tests/ui/cast_lossless_bool.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::cast_lossless)] diff --git a/tests/ui/cast_lossless_float.fixed b/tests/ui/cast_lossless_float.fixed index 32a9c1c4ae1a..e72a0096acce 100644 --- a/tests/ui/cast_lossless_float.fixed +++ b/tests/ui/cast_lossless_float.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] #![warn(clippy::cast_lossless)] diff --git a/tests/ui/cast_lossless_float.rs b/tests/ui/cast_lossless_float.rs index 6f5ddcfe09c8..dbcbaa9b8150 100644 --- a/tests/ui/cast_lossless_float.rs +++ b/tests/ui/cast_lossless_float.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] #![warn(clippy::cast_lossless)] diff --git a/tests/ui/cast_lossless_integer.fixed b/tests/ui/cast_lossless_integer.fixed index 925cbf25368f..7dab02084fc9 100644 --- a/tests/ui/cast_lossless_integer.fixed +++ b/tests/ui/cast_lossless_integer.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] #![warn(clippy::cast_lossless)] diff --git a/tests/ui/cast_lossless_integer.rs b/tests/ui/cast_lossless_integer.rs index c82bd9108d23..c24f73960b03 100644 --- a/tests/ui/cast_lossless_integer.rs +++ b/tests/ui/cast_lossless_integer.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] #![warn(clippy::cast_lossless)] diff --git a/tests/ui/cast_raw_slice_pointer_cast.fixed b/tests/ui/cast_raw_slice_pointer_cast.fixed index b70c19129511..9b6fee270ee9 100644 --- a/tests/ui/cast_raw_slice_pointer_cast.fixed +++ b/tests/ui/cast_raw_slice_pointer_cast.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cast_slice_from_raw_parts)] #[allow(unused_imports, unused_unsafe)] diff --git a/tests/ui/cast_raw_slice_pointer_cast.rs b/tests/ui/cast_raw_slice_pointer_cast.rs index c1b316765c96..c0bb81379905 100644 --- a/tests/ui/cast_raw_slice_pointer_cast.rs +++ b/tests/ui/cast_raw_slice_pointer_cast.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cast_slice_from_raw_parts)] #[allow(unused_imports, unused_unsafe)] diff --git a/tests/ui/cast_ref_to_mut.rs b/tests/ui/cast_ref_to_mut.rs deleted file mode 100644 index c48a734ba32c..000000000000 --- a/tests/ui/cast_ref_to_mut.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![warn(clippy::cast_ref_to_mut)] -#![allow(clippy::no_effect, clippy::borrow_as_ptr)] - -extern "C" { - // N.B., mutability can be easily incorrect in FFI calls -- as - // in C, the default is mutable pointers. - fn ffi(c: *mut u8); - fn int_ffi(c: *mut i32); -} - -fn main() { - let s = String::from("Hello"); - let a = &s; - unsafe { - let num = &3i32; - let mut_num = &mut 3i32; - // Should be warned against - (*(a as *const _ as *mut String)).push_str(" world"); - *(a as *const _ as *mut _) = String::from("Replaced"); - *(a as *const _ as *mut String) += " world"; - // Shouldn't be warned against - println!("{}", *(num as *const _ as *const i16)); - println!("{}", *(mut_num as *mut _ as *mut i16)); - ffi(a.as_ptr() as *mut _); - int_ffi(num as *const _ as *mut _); - int_ffi(&3 as *const _ as *mut _); - let mut value = 3; - let value: *const i32 = &mut value; - *(value as *const i16 as *mut i16) = 42; - } -} diff --git a/tests/ui/cast_ref_to_mut.stderr b/tests/ui/cast_ref_to_mut.stderr deleted file mode 100644 index aacd99437d9f..000000000000 --- a/tests/ui/cast_ref_to_mut.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error: casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:18:9 - | -LL | (*(a as *const _ as *mut String)).push_str(" world"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `-D clippy::cast-ref-to-mut` implied by `-D warnings` - -error: casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:19:9 - | -LL | *(a as *const _ as *mut _) = String::from("Replaced"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell` - --> $DIR/cast_ref_to_mut.rs:20:9 - | -LL | *(a as *const _ as *mut String) += " world"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors - diff --git a/tests/ui/cast_size.rs b/tests/ui/cast_size.rs index 595109be46bb..cd2184aea382 100644 --- a/tests/ui/cast_size.rs +++ b/tests/ui/cast_size.rs @@ -1,4 +1,4 @@ -// ignore-32bit +//@ignore-32bit #[warn( clippy::cast_precision_loss, clippy::cast_possible_truncation, diff --git a/tests/ui/cast_size_32bit.rs b/tests/ui/cast_size_32bit.rs index 99aac6deca32..7ca20d3ca4a7 100644 --- a/tests/ui/cast_size_32bit.rs +++ b/tests/ui/cast_size_32bit.rs @@ -1,4 +1,4 @@ -// ignore-64bit +//@ignore-64bit #[warn( clippy::cast_precision_loss, clippy::cast_possible_truncation, diff --git a/tests/ui/cast_size_32bit.stderr b/tests/ui/cast_size_32bit.stderr index 8990c3ba739b..fb51783a4878 100644 --- a/tests/ui/cast_size_32bit.stderr +++ b/tests/ui/cast_size_32bit.stderr @@ -4,7 +4,12 @@ error: casting `isize` to `i8` may truncate the value LL | 1isize as i8; | ^^^^^^^^^^^^ | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... = note: `-D clippy::cast-possible-truncation` implied by `-D warnings` +help: ... or use `try_from` and handle the error accordingly + | +LL | i8::try_from(1isize); + | ~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) --> $DIR/cast_size_32bit.rs:15:5 @@ -37,24 +42,48 @@ error: casting `isize` to `i32` may truncate the value on targets with 64-bit wi | LL | 1isize as i32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | i32::try_from(1isize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers --> $DIR/cast_size_32bit.rs:20:5 | LL | 1isize as u32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u32::try_from(1isize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers --> $DIR/cast_size_32bit.rs:21:5 | LL | 1usize as u32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u32::try_from(1usize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers --> $DIR/cast_size_32bit.rs:22:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | i32::try_from(1usize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers --> $DIR/cast_size_32bit.rs:22:5 @@ -69,18 +98,36 @@ error: casting `i64` to `isize` may truncate the value on targets with 32-bit wi | LL | 1i64 as isize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | isize::try_from(1i64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers --> $DIR/cast_size_32bit.rs:25:5 | LL | 1i64 as usize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | usize::try_from(1i64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers --> $DIR/cast_size_32bit.rs:26:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | isize::try_from(1u64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers --> $DIR/cast_size_32bit.rs:26:5 @@ -93,6 +140,12 @@ error: casting `u64` to `usize` may truncate the value on targets with 32-bit wi | LL | 1u64 as usize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | usize::try_from(1u64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers --> $DIR/cast_size_32bit.rs:28:5 diff --git a/tests/ui/cast_slice_different_sizes.rs b/tests/ui/cast_slice_different_sizes.rs index 24d7eb28a197..27e03ebb7197 100644 --- a/tests/ui/cast_slice_different_sizes.rs +++ b/tests/ui/cast_slice_different_sizes.rs @@ -1,4 +1,4 @@ -#![allow(clippy::let_unit_value)] +#![allow(clippy::let_unit_value, clippy::unnecessary_cast)] fn main() { let x: [i32; 3] = [1_i32, 2, 3]; @@ -23,7 +23,7 @@ fn main() { r_x as *const [i32] } as *const [u8]; - // Check that resores of the same size are detected through blocks + // Check that resources of the same size are detected through blocks let restore_block_1 = { r_x as *const [i32] } as *const [u8] as *const [u32]; let restore_block_2 = { ({ r_x as *const [i32] }) as *const [u8] } as *const [u32]; let restore_block_3 = { diff --git a/tests/ui/cfg_attr_rustfmt.fixed b/tests/ui/cfg_attr_rustfmt.fixed index b970b1209b65..13aadb7d3308 100644 --- a/tests/ui/cfg_attr_rustfmt.fixed +++ b/tests/ui/cfg_attr_rustfmt.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(stmt_expr_attributes)] #![allow(unused, clippy::no_effect, clippy::unnecessary_operation)] diff --git a/tests/ui/cfg_attr_rustfmt.rs b/tests/ui/cfg_attr_rustfmt.rs index 0a8e6a89d8a0..769c5d22b9da 100644 --- a/tests/ui/cfg_attr_rustfmt.rs +++ b/tests/ui/cfg_attr_rustfmt.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(stmt_expr_attributes)] #![allow(unused, clippy::no_effect, clippy::unnecessary_operation)] diff --git a/tests/ui/cfg_features.rs b/tests/ui/cfg_features.rs new file mode 100644 index 000000000000..bc4109c2c896 --- /dev/null +++ b/tests/ui/cfg_features.rs @@ -0,0 +1,12 @@ +#![warn(clippy::maybe_misused_cfg)] + +fn main() { + #[cfg(features = "not-really-a-feature")] + let _ = 1 + 2; + + #[cfg(all(feature = "right", features = "wrong"))] + let _ = 1 + 2; + + #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))] + let _ = 1 + 2; +} diff --git a/tests/ui/cfg_features.stderr b/tests/ui/cfg_features.stderr new file mode 100644 index 000000000000..00405985d48c --- /dev/null +++ b/tests/ui/cfg_features.stderr @@ -0,0 +1,28 @@ +error: feature may misspelled as features + --> $DIR/cfg_features.rs:4:11 + | +LL | #[cfg(features = "not-really-a-feature")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `feature = "not-really-a-feature"` + | + = note: `-D clippy::maybe-misused-cfg` implied by `-D warnings` + +error: feature may misspelled as features + --> $DIR/cfg_features.rs:7:34 + | +LL | #[cfg(all(feature = "right", features = "wrong"))] + | ^^^^^^^^^^^^^^^^^^ help: use: `feature = "wrong"` + +error: feature may misspelled as features + --> $DIR/cfg_features.rs:10:15 + | +LL | #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))] + | ^^^^^^^^^^^^^^^^^^^ help: use: `feature = "wrong1"` + +error: feature may misspelled as features + --> $DIR/cfg_features.rs:10:59 + | +LL | #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))] + | ^^^^^^^^^^^^^^^^^^^ help: use: `feature = "wrong2"` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/char_lit_as_u8_suggestions.fixed b/tests/ui/char_lit_as_u8_suggestions.fixed index 3dc3cb4e7573..ce2f149dc05e 100644 --- a/tests/ui/char_lit_as_u8_suggestions.fixed +++ b/tests/ui/char_lit_as_u8_suggestions.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::char_lit_as_u8)] diff --git a/tests/ui/char_lit_as_u8_suggestions.rs b/tests/ui/char_lit_as_u8_suggestions.rs index d379a0234942..ffad12fc6f95 100644 --- a/tests/ui/char_lit_as_u8_suggestions.rs +++ b/tests/ui/char_lit_as_u8_suggestions.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::char_lit_as_u8)] diff --git a/tests/ui/checked_conversions.fixed b/tests/ui/checked_conversions.fixed index e279ba3147bb..188e6d975952 100644 --- a/tests/ui/checked_conversions.fixed +++ b/tests/ui/checked_conversions.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( clippy::cast_lossless, diff --git a/tests/ui/checked_conversions.rs b/tests/ui/checked_conversions.rs index 9d7a40995c37..70f0f0975acd 100644 --- a/tests/ui/checked_conversions.rs +++ b/tests/ui/checked_conversions.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( clippy::cast_lossless, diff --git a/tests/ui/checked_unwrap/complex_conditionals.rs b/tests/ui/checked_unwrap/complex_conditionals.rs index ec082c73b44c..16e54a7d969e 100644 --- a/tests/ui/checked_unwrap/complex_conditionals.rs +++ b/tests/ui/checked_unwrap/complex_conditionals.rs @@ -1,5 +1,9 @@ #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] -#![allow(clippy::if_same_then_else, clippy::branches_sharing_code)] +#![allow( + clippy::if_same_then_else, + clippy::branches_sharing_code, + clippy::unnecessary_literal_unwrap +)] fn test_complex_conditions() { let x: Result<(), ()> = Ok(()); diff --git a/tests/ui/checked_unwrap/complex_conditionals.stderr b/tests/ui/checked_unwrap/complex_conditionals.stderr index d44d5072e485..c395c5ba06f2 100644 --- a/tests/ui/checked_unwrap/complex_conditionals.stderr +++ b/tests/ui/checked_unwrap/complex_conditionals.stderr @@ -1,5 +1,5 @@ error: called `unwrap` on `x` after checking its variant with `is_ok` - --> $DIR/complex_conditionals.rs:8:9 + --> $DIR/complex_conditionals.rs:12:9 | LL | if x.is_ok() && y.is_err() { | --------- the check is happening here @@ -14,7 +14,7 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> $DIR/complex_conditionals.rs:9:9 + --> $DIR/complex_conditionals.rs:13:9 | LL | if x.is_ok() && y.is_err() { | --------- because of this check @@ -29,7 +29,7 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> $DIR/complex_conditionals.rs:10:9 + --> $DIR/complex_conditionals.rs:14:9 | LL | if x.is_ok() && y.is_err() { | ---------- because of this check @@ -38,7 +38,7 @@ LL | y.unwrap(); // will panic | ^^^^^^^^^^ error: called `unwrap_err` on `y` after checking its variant with `is_err` - --> $DIR/complex_conditionals.rs:11:9 + --> $DIR/complex_conditionals.rs:15:9 | LL | if x.is_ok() && y.is_err() { | ---------- the check is happening here @@ -49,7 +49,7 @@ LL | y.unwrap_err(); // unnecessary = help: try using `if let` or `match` error: this call to `unwrap()` will always panic - --> $DIR/complex_conditionals.rs:25:9 + --> $DIR/complex_conditionals.rs:29:9 | LL | if x.is_ok() || y.is_ok() { | --------- because of this check @@ -58,7 +58,7 @@ LL | x.unwrap(); // will panic | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> $DIR/complex_conditionals.rs:26:9 + --> $DIR/complex_conditionals.rs:30:9 | LL | if x.is_ok() || y.is_ok() { | --------- the check is happening here @@ -69,7 +69,7 @@ LL | x.unwrap_err(); // unnecessary = help: try using `if let` or `match` error: this call to `unwrap()` will always panic - --> $DIR/complex_conditionals.rs:27:9 + --> $DIR/complex_conditionals.rs:31:9 | LL | if x.is_ok() || y.is_ok() { | --------- because of this check @@ -78,7 +78,7 @@ LL | y.unwrap(); // will panic | ^^^^^^^^^^ error: called `unwrap_err` on `y` after checking its variant with `is_ok` - --> $DIR/complex_conditionals.rs:28:9 + --> $DIR/complex_conditionals.rs:32:9 | LL | if x.is_ok() || y.is_ok() { | --------- the check is happening here @@ -89,7 +89,7 @@ LL | y.unwrap_err(); // unnecessary = help: try using `if let` or `match` error: called `unwrap` on `x` after checking its variant with `is_ok` - --> $DIR/complex_conditionals.rs:32:9 + --> $DIR/complex_conditionals.rs:36:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- the check is happening here @@ -99,7 +99,7 @@ LL | x.unwrap(); // unnecessary = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> $DIR/complex_conditionals.rs:33:9 + --> $DIR/complex_conditionals.rs:37:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- because of this check @@ -108,7 +108,7 @@ LL | x.unwrap_err(); // will panic | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> $DIR/complex_conditionals.rs:34:9 + --> $DIR/complex_conditionals.rs:38:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- because of this check @@ -117,7 +117,7 @@ LL | y.unwrap(); // will panic | ^^^^^^^^^^ error: called `unwrap_err` on `y` after checking its variant with `is_ok` - --> $DIR/complex_conditionals.rs:35:9 + --> $DIR/complex_conditionals.rs:39:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- the check is happening here @@ -128,7 +128,7 @@ LL | y.unwrap_err(); // unnecessary = help: try using `if let` or `match` error: called `unwrap` on `z` after checking its variant with `is_err` - --> $DIR/complex_conditionals.rs:36:9 + --> $DIR/complex_conditionals.rs:40:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | ---------- the check is happening here @@ -139,7 +139,7 @@ LL | z.unwrap(); // unnecessary = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> $DIR/complex_conditionals.rs:37:9 + --> $DIR/complex_conditionals.rs:41:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | ---------- because of this check @@ -148,7 +148,7 @@ LL | z.unwrap_err(); // will panic | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> $DIR/complex_conditionals.rs:45:9 + --> $DIR/complex_conditionals.rs:49:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- because of this check @@ -157,7 +157,7 @@ LL | x.unwrap(); // will panic | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> $DIR/complex_conditionals.rs:46:9 + --> $DIR/complex_conditionals.rs:50:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- the check is happening here @@ -168,7 +168,7 @@ LL | x.unwrap_err(); // unnecessary = help: try using `if let` or `match` error: called `unwrap` on `y` after checking its variant with `is_ok` - --> $DIR/complex_conditionals.rs:47:9 + --> $DIR/complex_conditionals.rs:51:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- the check is happening here @@ -179,7 +179,7 @@ LL | y.unwrap(); // unnecessary = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> $DIR/complex_conditionals.rs:48:9 + --> $DIR/complex_conditionals.rs:52:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- because of this check @@ -188,7 +188,7 @@ LL | y.unwrap_err(); // will panic | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> $DIR/complex_conditionals.rs:49:9 + --> $DIR/complex_conditionals.rs:53:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | ---------- because of this check @@ -197,7 +197,7 @@ LL | z.unwrap(); // will panic | ^^^^^^^^^^ error: called `unwrap_err` on `z` after checking its variant with `is_err` - --> $DIR/complex_conditionals.rs:50:9 + --> $DIR/complex_conditionals.rs:54:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | ---------- the check is happening here diff --git a/tests/ui/checked_unwrap/complex_conditionals_nested.rs b/tests/ui/checked_unwrap/complex_conditionals_nested.rs index 043ea4148dc5..e417cf833cbb 100644 --- a/tests/ui/checked_unwrap/complex_conditionals_nested.rs +++ b/tests/ui/checked_unwrap/complex_conditionals_nested.rs @@ -1,5 +1,9 @@ #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] -#![allow(clippy::if_same_then_else, clippy::branches_sharing_code)] +#![allow( + clippy::if_same_then_else, + clippy::branches_sharing_code, + clippy::unnecessary_literal_unwrap +)] fn test_nested() { fn nested() { diff --git a/tests/ui/checked_unwrap/complex_conditionals_nested.stderr b/tests/ui/checked_unwrap/complex_conditionals_nested.stderr index 542ab53300c0..049a69d93bfe 100644 --- a/tests/ui/checked_unwrap/complex_conditionals_nested.stderr +++ b/tests/ui/checked_unwrap/complex_conditionals_nested.stderr @@ -1,5 +1,5 @@ error: called `unwrap` on `x` after checking its variant with `is_some` - --> $DIR/complex_conditionals_nested.rs:8:13 + --> $DIR/complex_conditionals_nested.rs:12:13 | LL | if x.is_some() { | -------------- help: try: `if let Some(..) = x` @@ -13,7 +13,7 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> $DIR/complex_conditionals_nested.rs:10:13 + --> $DIR/complex_conditionals_nested.rs:14:13 | LL | if x.is_some() { | ----------- because of this check diff --git a/tests/ui/checked_unwrap/simple_conditionals.rs b/tests/ui/checked_unwrap/simple_conditionals.rs index 82dce81979fd..61042bb90d27 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.rs +++ b/tests/ui/checked_unwrap/simple_conditionals.rs @@ -1,6 +1,10 @@ #![feature(lint_reasons)] #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] -#![allow(clippy::if_same_then_else, clippy::branches_sharing_code)] +#![allow( + clippy::if_same_then_else, + clippy::branches_sharing_code, + clippy::unnecessary_literal_unwrap +)] macro_rules! m { ($a:expr) => { diff --git a/tests/ui/checked_unwrap/simple_conditionals.stderr b/tests/ui/checked_unwrap/simple_conditionals.stderr index ef6882742223..93809f6551ad 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.stderr +++ b/tests/ui/checked_unwrap/simple_conditionals.stderr @@ -1,5 +1,5 @@ error: called `unwrap` on `x` after checking its variant with `is_some` - --> $DIR/simple_conditionals.rs:40:9 + --> $DIR/simple_conditionals.rs:44:9 | LL | if x.is_some() { | -------------- help: try: `if let Some(..) = x` @@ -13,7 +13,7 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `expect` on `x` after checking its variant with `is_some` - --> $DIR/simple_conditionals.rs:41:9 + --> $DIR/simple_conditionals.rs:45:9 | LL | if x.is_some() { | -------------- help: try: `if let Some(..) = x` @@ -22,7 +22,7 @@ LL | x.expect("an error message"); // unnecessary | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> $DIR/simple_conditionals.rs:43:9 + --> $DIR/simple_conditionals.rs:47:9 | LL | if x.is_some() { | ----------- because of this check @@ -37,7 +37,7 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `expect()` will always panic - --> $DIR/simple_conditionals.rs:44:9 + --> $DIR/simple_conditionals.rs:48:9 | LL | if x.is_some() { | ----------- because of this check @@ -46,7 +46,7 @@ LL | x.expect("an error message"); // will panic | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> $DIR/simple_conditionals.rs:47:9 + --> $DIR/simple_conditionals.rs:51:9 | LL | if x.is_none() { | ----------- because of this check @@ -54,7 +54,7 @@ LL | x.unwrap(); // will panic | ^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_none` - --> $DIR/simple_conditionals.rs:49:9 + --> $DIR/simple_conditionals.rs:53:9 | LL | if x.is_none() { | -------------- help: try: `if let Some(..) = x` @@ -63,7 +63,7 @@ LL | x.unwrap(); // unnecessary | ^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_some` - --> $DIR/simple_conditionals.rs:8:13 + --> $DIR/simple_conditionals.rs:12:13 | LL | if $a.is_some() { | --------------- help: try: `if let Some(..) = x` @@ -76,7 +76,7 @@ LL | m!(x); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: called `unwrap` on `x` after checking its variant with `is_ok` - --> $DIR/simple_conditionals.rs:57:9 + --> $DIR/simple_conditionals.rs:61:9 | LL | if x.is_ok() { | ------------ help: try: `if let Ok(..) = x` @@ -84,7 +84,7 @@ LL | x.unwrap(); // unnecessary | ^^^^^^^^^^ error: called `expect` on `x` after checking its variant with `is_ok` - --> $DIR/simple_conditionals.rs:58:9 + --> $DIR/simple_conditionals.rs:62:9 | LL | if x.is_ok() { | ------------ help: try: `if let Ok(..) = x` @@ -93,7 +93,7 @@ LL | x.expect("an error message"); // unnecessary | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> $DIR/simple_conditionals.rs:59:9 + --> $DIR/simple_conditionals.rs:63:9 | LL | if x.is_ok() { | --------- because of this check @@ -102,7 +102,7 @@ LL | x.unwrap_err(); // will panic | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> $DIR/simple_conditionals.rs:61:9 + --> $DIR/simple_conditionals.rs:65:9 | LL | if x.is_ok() { | --------- because of this check @@ -111,7 +111,7 @@ LL | x.unwrap(); // will panic | ^^^^^^^^^^ error: this call to `expect()` will always panic - --> $DIR/simple_conditionals.rs:62:9 + --> $DIR/simple_conditionals.rs:66:9 | LL | if x.is_ok() { | --------- because of this check @@ -120,7 +120,7 @@ LL | x.expect("an error message"); // will panic | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> $DIR/simple_conditionals.rs:63:9 + --> $DIR/simple_conditionals.rs:67:9 | LL | if x.is_ok() { | ------------ help: try: `if let Err(..) = x` @@ -129,7 +129,7 @@ LL | x.unwrap_err(); // unnecessary | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> $DIR/simple_conditionals.rs:66:9 + --> $DIR/simple_conditionals.rs:70:9 | LL | if x.is_err() { | ---------- because of this check @@ -137,7 +137,7 @@ LL | x.unwrap(); // will panic | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_err` - --> $DIR/simple_conditionals.rs:67:9 + --> $DIR/simple_conditionals.rs:71:9 | LL | if x.is_err() { | ------------- help: try: `if let Err(..) = x` @@ -146,7 +146,7 @@ LL | x.unwrap_err(); // unnecessary | ^^^^^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_err` - --> $DIR/simple_conditionals.rs:69:9 + --> $DIR/simple_conditionals.rs:73:9 | LL | if x.is_err() { | ------------- help: try: `if let Ok(..) = x` @@ -155,7 +155,7 @@ LL | x.unwrap(); // unnecessary | ^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> $DIR/simple_conditionals.rs:70:9 + --> $DIR/simple_conditionals.rs:74:9 | LL | if x.is_err() { | ---------- because of this check diff --git a/tests/ui/clear_with_drain.fixed b/tests/ui/clear_with_drain.fixed index 2d9545eeed19..23b11573f043 100644 --- a/tests/ui/clear_with_drain.fixed +++ b/tests/ui/clear_with_drain.fixed @@ -1,4 +1,16 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= // run-rustfix +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +//@run-rustfix +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +//@run-rustfix +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) #![allow(unused)] #![warn(clippy::clear_with_drain)] diff --git a/tests/ui/clear_with_drain.rs b/tests/ui/clear_with_drain.rs index 4d60ee46e186..9d81b90ca043 100644 --- a/tests/ui/clear_with_drain.rs +++ b/tests/ui/clear_with_drain.rs @@ -1,4 +1,16 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= // run-rustfix +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +//@run-rustfix +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +//@run-rustfix +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) #![allow(unused)] #![warn(clippy::clear_with_drain)] diff --git a/tests/ui/clone_on_copy.fixed b/tests/ui/clone_on_copy.fixed index 72b122270981..a720711585bb 100644 --- a/tests/ui/clone_on_copy.fixed +++ b/tests/ui/clone_on_copy.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, diff --git a/tests/ui/clone_on_copy.rs b/tests/ui/clone_on_copy.rs index 03e210ebad98..2c5fac8faf56 100644 --- a/tests/ui/clone_on_copy.rs +++ b/tests/ui/clone_on_copy.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, diff --git a/tests/ui/clone_on_copy_impl.rs b/tests/ui/clone_on_copy_impl.rs index 8f9f2a0db8c4..618249e47d98 100644 --- a/tests/ui/clone_on_copy_impl.rs +++ b/tests/ui/clone_on_copy_impl.rs @@ -1,3 +1,13 @@ +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::incorrect_clone_impl_on_copy_type)] +======= +#![allow(clippy::needless_clone_impl)] +>>>>>>> 67d5e6ec3 (add lint [`needless_clone_impl`]) +======= +#![allow(clippy::incorrect_clone_impl_on_copy_type)] +>>>>>>> 10cc1684c (rename lint and disallow `clone_from`) + use std::fmt; use std::marker::PhantomData; diff --git a/tests/ui/cloned_instead_of_copied.fixed b/tests/ui/cloned_instead_of_copied.fixed index ecbfc1feedf6..34bd2233440b 100644 --- a/tests/ui/cloned_instead_of_copied.fixed +++ b/tests/ui/cloned_instead_of_copied.fixed @@ -1,7 +1,8 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cloned_instead_of_copied)] #![allow(unused)] +#![allow(clippy::useless_vec)] fn main() { // yay diff --git a/tests/ui/cloned_instead_of_copied.rs b/tests/ui/cloned_instead_of_copied.rs index 163dc3dddce6..fa8444937b6b 100644 --- a/tests/ui/cloned_instead_of_copied.rs +++ b/tests/ui/cloned_instead_of_copied.rs @@ -1,7 +1,8 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cloned_instead_of_copied)] #![allow(unused)] +#![allow(clippy::useless_vec)] fn main() { // yay diff --git a/tests/ui/cloned_instead_of_copied.stderr b/tests/ui/cloned_instead_of_copied.stderr index e0361acd9560..3ce482006e94 100644 --- a/tests/ui/cloned_instead_of_copied.stderr +++ b/tests/ui/cloned_instead_of_copied.stderr @@ -1,5 +1,5 @@ error: used `cloned` where `copied` could be used instead - --> $DIR/cloned_instead_of_copied.rs:8:24 + --> $DIR/cloned_instead_of_copied.rs:9:24 | LL | let _ = [1].iter().cloned(); | ^^^^^^ help: try: `copied` @@ -7,43 +7,43 @@ LL | let _ = [1].iter().cloned(); = note: `-D clippy::cloned-instead-of-copied` implied by `-D warnings` error: used `cloned` where `copied` could be used instead - --> $DIR/cloned_instead_of_copied.rs:9:31 + --> $DIR/cloned_instead_of_copied.rs:10:31 | LL | let _ = vec!["hi"].iter().cloned(); | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> $DIR/cloned_instead_of_copied.rs:10:22 + --> $DIR/cloned_instead_of_copied.rs:11:22 | LL | let _ = Some(&1).cloned(); | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> $DIR/cloned_instead_of_copied.rs:11:34 + --> $DIR/cloned_instead_of_copied.rs:12:34 | LL | let _ = Box::new([1].iter()).cloned(); | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> $DIR/cloned_instead_of_copied.rs:12:32 + --> $DIR/cloned_instead_of_copied.rs:13:32 | LL | let _ = Box::new(Some(&1)).cloned(); | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> $DIR/cloned_instead_of_copied.rs:28:22 + --> $DIR/cloned_instead_of_copied.rs:29:22 | LL | let _ = Some(&1).cloned(); // Option::copied needs 1.35 | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> $DIR/cloned_instead_of_copied.rs:33:24 + --> $DIR/cloned_instead_of_copied.rs:34:24 | LL | let _ = [1].iter().cloned(); // Iterator::copied needs 1.36 | ^^^^^^ help: try: `copied` error: used `cloned` where `copied` could be used instead - --> $DIR/cloned_instead_of_copied.rs:34:22 + --> $DIR/cloned_instead_of_copied.rs:35:22 | LL | let _ = Some(&1).cloned(); | ^^^^^^ help: try: `copied` diff --git a/tests/ui/cmp_nan.rs b/tests/ui/cmp_nan.rs deleted file mode 100644 index 64ca52b010a7..000000000000 --- a/tests/ui/cmp_nan.rs +++ /dev/null @@ -1,34 +0,0 @@ -const NAN_F32: f32 = f32::NAN; -const NAN_F64: f64 = f64::NAN; - -#[warn(clippy::cmp_nan)] -#[allow(clippy::float_cmp, clippy::no_effect, clippy::unnecessary_operation)] -fn main() { - let x = 5f32; - x == f32::NAN; - x != f32::NAN; - x < f32::NAN; - x > f32::NAN; - x <= f32::NAN; - x >= f32::NAN; - x == NAN_F32; - x != NAN_F32; - x < NAN_F32; - x > NAN_F32; - x <= NAN_F32; - x >= NAN_F32; - - let y = 0f64; - y == f64::NAN; - y != f64::NAN; - y < f64::NAN; - y > f64::NAN; - y <= f64::NAN; - y >= f64::NAN; - y == NAN_F64; - y != NAN_F64; - y < NAN_F64; - y > NAN_F64; - y <= NAN_F64; - y >= NAN_F64; -} diff --git a/tests/ui/cmp_nan.stderr b/tests/ui/cmp_nan.stderr deleted file mode 100644 index 867516661a53..000000000000 --- a/tests/ui/cmp_nan.stderr +++ /dev/null @@ -1,148 +0,0 @@ -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:8:5 - | -LL | x == f32::NAN; - | ^^^^^^^^^^^^^ - | - = note: `-D clippy::cmp-nan` implied by `-D warnings` - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:9:5 - | -LL | x != f32::NAN; - | ^^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:10:5 - | -LL | x < f32::NAN; - | ^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:11:5 - | -LL | x > f32::NAN; - | ^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:12:5 - | -LL | x <= f32::NAN; - | ^^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:13:5 - | -LL | x >= f32::NAN; - | ^^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:14:5 - | -LL | x == NAN_F32; - | ^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:15:5 - | -LL | x != NAN_F32; - | ^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:16:5 - | -LL | x < NAN_F32; - | ^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:17:5 - | -LL | x > NAN_F32; - | ^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:18:5 - | -LL | x <= NAN_F32; - | ^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:19:5 - | -LL | x >= NAN_F32; - | ^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:22:5 - | -LL | y == f64::NAN; - | ^^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:23:5 - | -LL | y != f64::NAN; - | ^^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:24:5 - | -LL | y < f64::NAN; - | ^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:25:5 - | -LL | y > f64::NAN; - | ^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:26:5 - | -LL | y <= f64::NAN; - | ^^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:27:5 - | -LL | y >= f64::NAN; - | ^^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:28:5 - | -LL | y == NAN_F64; - | ^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:29:5 - | -LL | y != NAN_F64; - | ^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:30:5 - | -LL | y < NAN_F64; - | ^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:31:5 - | -LL | y > NAN_F64; - | ^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:32:5 - | -LL | y <= NAN_F64; - | ^^^^^^^^^^^^ - -error: doomed comparison with `NAN`, use `{f32,f64}::is_nan()` instead - --> $DIR/cmp_nan.rs:33:5 - | -LL | y >= NAN_F64; - | ^^^^^^^^^^^^ - -error: aborting due to 24 previous errors - diff --git a/tests/ui/cmp_owned/asymmetric_partial_eq.fixed b/tests/ui/cmp_owned/asymmetric_partial_eq.fixed index abd059c23080..3ea1cc680cdf 100644 --- a/tests/ui/cmp_owned/asymmetric_partial_eq.fixed +++ b/tests/ui/cmp_owned/asymmetric_partial_eq.fixed @@ -1,5 +1,14 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow( + unused, + clippy::needless_if, + clippy::redundant_clone, + clippy::derive_partial_eq_without_eq +)] // See #5700 +======= #![allow(unused, clippy::redundant_clone, clippy::derive_partial_eq_without_eq)] // See #5700 +>>>>>>> e4f5d83fa (Fixed formatting.) // Define the types in each module to avoid trait impls leaking between modules. macro_rules! impl_types { diff --git a/tests/ui/cmp_owned/asymmetric_partial_eq.rs b/tests/ui/cmp_owned/asymmetric_partial_eq.rs index 020ef5f840bd..e6955d75aa9c 100644 --- a/tests/ui/cmp_owned/asymmetric_partial_eq.rs +++ b/tests/ui/cmp_owned/asymmetric_partial_eq.rs @@ -1,5 +1,14 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow( + unused, + clippy::needless_if, + clippy::redundant_clone, + clippy::derive_partial_eq_without_eq +)] // See #5700 +======= #![allow(unused, clippy::redundant_clone, clippy::derive_partial_eq_without_eq)] // See #5700 +>>>>>>> e4f5d83fa (Fixed formatting.) // Define the types in each module to avoid trait impls leaking between modules. macro_rules! impl_types { diff --git a/tests/ui/cmp_owned/asymmetric_partial_eq.stderr b/tests/ui/cmp_owned/asymmetric_partial_eq.stderr index 43bf8851fc62..4714a0daaa68 100644 --- a/tests/ui/cmp_owned/asymmetric_partial_eq.stderr +++ b/tests/ui/cmp_owned/asymmetric_partial_eq.stderr @@ -1,5 +1,5 @@ error: this creates an owned instance just for comparison - --> $DIR/asymmetric_partial_eq.rs:42:12 + --> $DIR/asymmetric_partial_eq.rs:47:12 | LL | if borrowed.to_owned() == owned {} | ^^^^^^^^^^^^^^^^^^^ help: try: `borrowed` @@ -7,7 +7,7 @@ LL | if borrowed.to_owned() == owned {} = note: `-D clippy::cmp-owned` implied by `-D warnings` error: this creates an owned instance just for comparison - --> $DIR/asymmetric_partial_eq.rs:43:21 + --> $DIR/asymmetric_partial_eq.rs:48:21 | LL | if owned == borrowed.to_owned() {} | ---------^^^^^^^^^^^^^^^^^^^ @@ -15,13 +15,13 @@ LL | if owned == borrowed.to_owned() {} | help: try: `borrowed == owned` error: this creates an owned instance just for comparison - --> $DIR/asymmetric_partial_eq.rs:61:21 + --> $DIR/asymmetric_partial_eq.rs:66:21 | LL | if owned == borrowed.to_owned() {} | ^^^^^^^^^^^^^^^^^^^ help: try: `borrowed` error: this creates an owned instance just for comparison - --> $DIR/asymmetric_partial_eq.rs:62:12 + --> $DIR/asymmetric_partial_eq.rs:67:12 | LL | if borrowed.to_owned() == owned {} | ^^^^^^^^^^^^^^^^^^^--------- @@ -29,7 +29,7 @@ LL | if borrowed.to_owned() == owned {} | help: try: `owned == borrowed` error: this creates an owned instance just for comparison - --> $DIR/asymmetric_partial_eq.rs:88:20 + --> $DIR/asymmetric_partial_eq.rs:93:20 | LL | if "Hi" == borrowed.to_string() {} | --------^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | if "Hi" == borrowed.to_string() {} | help: try: `borrowed == "Hi"` error: this creates an owned instance just for comparison - --> $DIR/asymmetric_partial_eq.rs:89:12 + --> $DIR/asymmetric_partial_eq.rs:94:12 | LL | if borrowed.to_string() == "Hi" {} | ^^^^^^^^^^^^^^^^^^^^ help: try: `borrowed` diff --git a/tests/ui/cmp_owned/comparison_flip.fixed b/tests/ui/cmp_owned/comparison_flip.fixed index 44e41bdd1148..b1133f2a59f7 100644 --- a/tests/ui/cmp_owned/comparison_flip.fixed +++ b/tests/ui/cmp_owned/comparison_flip.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix use std::fmt::{self, Display}; diff --git a/tests/ui/cmp_owned/comparison_flip.rs b/tests/ui/cmp_owned/comparison_flip.rs index 662673abb62d..091a9aa65c0a 100644 --- a/tests/ui/cmp_owned/comparison_flip.rs +++ b/tests/ui/cmp_owned/comparison_flip.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix use std::fmt::{self, Display}; diff --git a/tests/ui/cmp_owned/with_suggestion.fixed b/tests/ui/cmp_owned/with_suggestion.fixed index b28c4378e33c..bf1a58588a85 100644 --- a/tests/ui/cmp_owned/with_suggestion.fixed +++ b/tests/ui/cmp_owned/with_suggestion.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::cmp_owned)] #[allow(clippy::unnecessary_operation, clippy::no_effect, unused_must_use, clippy::eq_op)] @@ -31,7 +31,7 @@ struct Foo; impl PartialEq for Foo { // Allow this here, because it emits the lint // without a suggestion. This is tested in - // `tests/ui/cmp_owned/without_suggestion.rs` + // `$DIR/without_suggestion.rs` #[allow(clippy::cmp_owned)] fn eq(&self, other: &Self) -> bool { self.to_owned() == *other diff --git a/tests/ui/cmp_owned/with_suggestion.rs b/tests/ui/cmp_owned/with_suggestion.rs index c1089010fe10..f3f663670eb1 100644 --- a/tests/ui/cmp_owned/with_suggestion.rs +++ b/tests/ui/cmp_owned/with_suggestion.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::cmp_owned)] #[allow(clippy::unnecessary_operation, clippy::no_effect, unused_must_use, clippy::eq_op)] diff --git a/tests/ui/cognitive_complexity.stderr b/tests/ui/cognitive_complexity.stderr index 5824631fa83b..d867246301ab 100644 --- a/tests/ui/cognitive_complexity.stderr +++ b/tests/ui/cognitive_complexity.stderr @@ -39,6 +39,14 @@ LL | fn bar() { | = help: you could split it up into multiple smaller functions +error: the function has a cognitive complexity of (2/1) + --> $DIR/cognitive_complexity.rs:178:4 + | +LL | fn dont_warn_on_tests() { + | ^^^^^^^^^^^^^^^^^^ + | + = help: you could split it up into multiple smaller functions + error: the function has a cognitive complexity of (2/1) --> $DIR/cognitive_complexity.rs:186:4 | @@ -151,5 +159,5 @@ LL | pub async fn async_method() { | = help: you could split it up into multiple smaller functions -error: aborting due to 19 previous errors +error: aborting due to 20 previous errors diff --git a/tests/ui/collapsible_else_if.fixed b/tests/ui/collapsible_else_if.fixed index d6a5a7850679..b85df6d73385 100644 --- a/tests/ui/collapsible_else_if.fixed +++ b/tests/ui/collapsible_else_if.fixed @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_if)] +======= #![allow(clippy::assertions_on_constants, clippy::equatable_if_let)] +>>>>>>> e4f5d83fa (Fixed formatting.) #[rustfmt::skip] #[warn(clippy::collapsible_if)] diff --git a/tests/ui/collapsible_else_if.rs b/tests/ui/collapsible_else_if.rs index 4399fc8b2bd1..ba024828e347 100644 --- a/tests/ui/collapsible_else_if.rs +++ b/tests/ui/collapsible_else_if.rs @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_if)] +======= #![allow(clippy::assertions_on_constants, clippy::equatable_if_let)] +>>>>>>> e4f5d83fa (Fixed formatting.) #[rustfmt::skip] #[warn(clippy::collapsible_if)] diff --git a/tests/ui/collapsible_if.fixed b/tests/ui/collapsible_if.fixed index 6bb7682bae95..62bb2d8bf582 100644 --- a/tests/ui/collapsible_if.fixed +++ b/tests/ui/collapsible_if.fixed @@ -1,5 +1,22 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow( + clippy::assertions_on_constants, + clippy::equatable_if_let, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::needless_if, +======= +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + clippy::needless_if, +>>>>>>> 26f50395b (Add `needless_if` lint) + clippy::nonminimal_bool, + clippy::eq_op +)] +======= #![allow(clippy::assertions_on_constants, clippy::equatable_if_let)] +>>>>>>> e4f5d83fa (Fixed formatting.) #[rustfmt::skip] #[warn(clippy::collapsible_if)] diff --git a/tests/ui/collapsible_if.rs b/tests/ui/collapsible_if.rs index e216a9ee54c9..6f99ef2a1304 100644 --- a/tests/ui/collapsible_if.rs +++ b/tests/ui/collapsible_if.rs @@ -1,5 +1,22 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow( + clippy::assertions_on_constants, + clippy::equatable_if_let, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::needless_if, +======= +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + clippy::needless_if, +>>>>>>> 26f50395b (Add `needless_if` lint) + clippy::nonminimal_bool, + clippy::eq_op +)] +======= #![allow(clippy::assertions_on_constants, clippy::equatable_if_let)] +>>>>>>> e4f5d83fa (Fixed formatting.) #[rustfmt::skip] #[warn(clippy::collapsible_if)] diff --git a/tests/ui/collapsible_if.stderr b/tests/ui/collapsible_if.stderr index 6327444df21d..4c3dd0c70ded 100644 --- a/tests/ui/collapsible_if.stderr +++ b/tests/ui/collapsible_if.stderr @@ -1,5 +1,13 @@ error: this `if` statement can be collapsed - --> $DIR/collapsible_if.rs:9:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/collapsible_if.rs:15:5 +======= + --> $DIR/collapsible_if.rs:14:5 +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + --> $DIR/collapsible_if.rs:15:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / if x == "hello" { LL | | if y == "world" { @@ -17,7 +25,15 @@ LL + } | error: this `if` statement can be collapsed - --> $DIR/collapsible_if.rs:15:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/collapsible_if.rs:21:5 +======= + --> $DIR/collapsible_if.rs:20:5 +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + --> $DIR/collapsible_if.rs:21:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / if x == "hello" || x == "world" { LL | | if y == "world" || y == "hello" { @@ -34,7 +50,15 @@ LL + } | error: this `if` statement can be collapsed - --> $DIR/collapsible_if.rs:21:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/collapsible_if.rs:27:5 +======= + --> $DIR/collapsible_if.rs:26:5 +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + --> $DIR/collapsible_if.rs:27:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / if x == "hello" && x == "world" { LL | | if y == "world" || y == "hello" { @@ -51,7 +75,15 @@ LL + } | error: this `if` statement can be collapsed - --> $DIR/collapsible_if.rs:27:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/collapsible_if.rs:33:5 +======= + --> $DIR/collapsible_if.rs:32:5 +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + --> $DIR/collapsible_if.rs:33:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / if x == "hello" || x == "world" { LL | | if y == "world" && y == "hello" { @@ -68,7 +100,15 @@ LL + } | error: this `if` statement can be collapsed - --> $DIR/collapsible_if.rs:33:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/collapsible_if.rs:39:5 +======= + --> $DIR/collapsible_if.rs:38:5 +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + --> $DIR/collapsible_if.rs:39:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / if x == "hello" && x == "world" { LL | | if y == "world" && y == "hello" { @@ -85,7 +125,15 @@ LL + } | error: this `if` statement can be collapsed - --> $DIR/collapsible_if.rs:39:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/collapsible_if.rs:45:5 +======= + --> $DIR/collapsible_if.rs:44:5 +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + --> $DIR/collapsible_if.rs:45:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / if 42 == 1337 { LL | | if 'a' != 'A' { @@ -102,7 +150,15 @@ LL + } | error: this `if` statement can be collapsed - --> $DIR/collapsible_if.rs:95:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/collapsible_if.rs:101:5 +======= + --> $DIR/collapsible_if.rs:100:5 +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + --> $DIR/collapsible_if.rs:101:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / if x == "hello" { LL | | if y == "world" { // Collapsible @@ -119,7 +175,15 @@ LL + } | error: this `if` statement can be collapsed - --> $DIR/collapsible_if.rs:154:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/collapsible_if.rs:160:5 +======= + --> $DIR/collapsible_if.rs:159:5 +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + --> $DIR/collapsible_if.rs:160:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / if matches!(true, true) { LL | | if matches!(true, true) {} @@ -127,7 +191,15 @@ LL | | } | |_____^ help: collapse nested if block: `if matches!(true, true) && matches!(true, true) {}` error: this `if` statement can be collapsed - --> $DIR/collapsible_if.rs:159:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/collapsible_if.rs:165:5 +======= + --> $DIR/collapsible_if.rs:164:5 +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + --> $DIR/collapsible_if.rs:165:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / if matches!(true, true) && truth() { LL | | if matches!(true, true) {} diff --git a/tests/ui/collapsible_str_replace.fixed b/tests/ui/collapsible_str_replace.fixed index 9792ae9ed6b8..ba6c1769a9a3 100644 --- a/tests/ui/collapsible_str_replace.fixed +++ b/tests/ui/collapsible_str_replace.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::collapsible_str_replace)] diff --git a/tests/ui/collapsible_str_replace.rs b/tests/ui/collapsible_str_replace.rs index baee185b79ea..f5871be65be1 100644 --- a/tests/ui/collapsible_str_replace.rs +++ b/tests/ui/collapsible_str_replace.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::collapsible_str_replace)] diff --git a/tests/ui/collection_is_never_read.rs b/tests/ui/collection_is_never_read.rs index 2c1a42a72c14..17d622e746c1 100644 --- a/tests/ui/collection_is_never_read.rs +++ b/tests/ui/collection_is_never_read.rs @@ -1,4 +1,4 @@ -#![allow(unused)] +#![allow(unused, clippy::useless_vec)] #![warn(clippy::collection_is_never_read)] use std::collections::{HashMap, HashSet}; @@ -169,6 +169,13 @@ fn function_argument() { foo(&x); } +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) fn supported_types() { let mut x = std::collections::BTreeMap::new(); // WARNING x.insert(true, 1); @@ -200,4 +207,93 @@ fn supported_types() { let mut x = std::collections::VecDeque::new(); // WARNING x.push_front(1); +======= +<<<<<<< HEAD +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) +fn string() { + // Do lint (write without read) + let mut s = String::new(); + s.push_str("Hello, World!"); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) +======= +fn supported_types() { + let mut x = std::collections::BTreeMap::new(); // WARNING + x.insert(true, 1); +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) + + let mut x = std::collections::BTreeSet::new(); // WARNING + x.insert(1); + + let mut x = std::collections::BinaryHeap::new(); // WARNING + x.push(1); + +<<<<<<< HEAD +<<<<<<< HEAD +======= +======= +fn supported_types() { + let mut x = std::collections::BTreeMap::new(); // WARNING + x.insert(true, 1); +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) + + let mut x = std::collections::BTreeSet::new(); // WARNING + x.insert(1); + + let mut x = std::collections::BinaryHeap::new(); // WARNING + x.push(1); + +<<<<<<< HEAD +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) + // Do lint the first line, but not the second + let mut s = String::from("Hello, World!"); + let t = String::from("foo, bar"); + s = t; +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) + let mut x = std::collections::HashMap::new(); // WARNING + x.insert(1, 2); + + let mut x = std::collections::HashSet::new(); // WARNING + x.insert(1); + + let mut x = std::collections::LinkedList::new(); // WARNING + x.push_front(1); + + let mut x = Some(true); // WARNING + x.insert(false); + + let mut x = String::from("hello"); // WARNING + x.push('!'); + + let mut x = Vec::new(); // WARNING + x.clear(); + x.push(1); + + let mut x = std::collections::VecDeque::new(); // WARNING + x.push_front(1); +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) } diff --git a/tests/ui/collection_is_never_read.stderr b/tests/ui/collection_is_never_read.stderr index 982cb445534a..5d3a06b81c35 100644 --- a/tests/ui/collection_is_never_read.stderr +++ b/tests/ui/collection_is_never_read.stderr @@ -61,6 +61,13 @@ LL | let x = vec![1, 2, 3]; // WARNING | ^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) --> $DIR/collection_is_never_read.rs:173:5 | LL | let mut x = std::collections::BTreeMap::new(); // WARNING @@ -121,4 +128,145 @@ LL | let mut x = std::collections::VecDeque::new(); // WARNING | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 20 previous errors +======= + --> $DIR/collection_is_never_read.rs:174:5 +======= + --> $DIR/collection_is_never_read.rs:173:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) + | +LL | let mut x = std::collections::BTreeMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:176:5 + | +LL | let mut x = std::collections::BTreeSet::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +<<<<<<< HEAD +error: aborting due to 12 previous errors +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +error: collection is never read + --> $DIR/collection_is_never_read.rs:179:5 + | +LL | let mut x = std::collections::BinaryHeap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:182:5 + | +LL | let mut x = std::collections::HashMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:185:5 + | +LL | let mut x = std::collections::HashSet::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:188:5 + | +LL | let mut x = std::collections::LinkedList::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:191:5 + | +LL | let mut x = Some(true); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:194:5 + | +LL | let mut x = String::from("hello"); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:197:5 + | +LL | let mut x = Vec::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:201:5 + | +LL | let mut x = std::collections::VecDeque::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 20 previous errors +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +<<<<<<< HEAD +======= + --> $DIR/collection_is_never_read.rs:174:5 +======= + --> $DIR/collection_is_never_read.rs:173:5 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) + | +LL | let mut x = std::collections::BTreeMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:176:5 + | +LL | let mut x = std::collections::BTreeSet::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +<<<<<<< HEAD +error: aborting due to 12 previous errors +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +error: collection is never read + --> $DIR/collection_is_never_read.rs:179:5 + | +LL | let mut x = std::collections::BinaryHeap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:182:5 + | +LL | let mut x = std::collections::HashMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:185:5 + | +LL | let mut x = std::collections::HashSet::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:188:5 + | +LL | let mut x = std::collections::LinkedList::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:191:5 + | +LL | let mut x = Some(true); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:194:5 + | +LL | let mut x = String::from("hello"); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:197:5 + | +LL | let mut x = Vec::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:201:5 + | +LL | let mut x = std::collections::VecDeque::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 20 previous errors +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) diff --git a/tests/ui/comparison_to_empty.fixed b/tests/ui/comparison_to_empty.fixed index 261024caca76..c92dd509ebb2 100644 --- a/tests/ui/comparison_to_empty.fixed +++ b/tests/ui/comparison_to_empty.fixed @@ -1,6 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::comparison_to_empty)] +#![allow(clippy::useless_vec)] fn main() { // Disallow comparisons to empty diff --git a/tests/ui/comparison_to_empty.rs b/tests/ui/comparison_to_empty.rs index 98ddd9749516..b3489714380a 100644 --- a/tests/ui/comparison_to_empty.rs +++ b/tests/ui/comparison_to_empty.rs @@ -1,6 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::comparison_to_empty)] +#![allow(clippy::useless_vec)] fn main() { // Disallow comparisons to empty diff --git a/tests/ui/comparison_to_empty.stderr b/tests/ui/comparison_to_empty.stderr index f69d6bd5255d..cc09b17eb895 100644 --- a/tests/ui/comparison_to_empty.stderr +++ b/tests/ui/comparison_to_empty.stderr @@ -1,5 +1,5 @@ error: comparison to empty slice - --> $DIR/comparison_to_empty.rs:8:13 + --> $DIR/comparison_to_empty.rs:9:13 | LL | let _ = s == ""; | ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()` @@ -7,19 +7,19 @@ LL | let _ = s == ""; = note: `-D clippy::comparison-to-empty` implied by `-D warnings` error: comparison to empty slice - --> $DIR/comparison_to_empty.rs:9:13 + --> $DIR/comparison_to_empty.rs:10:13 | LL | let _ = s != ""; | ^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!s.is_empty()` error: comparison to empty slice - --> $DIR/comparison_to_empty.rs:12:13 + --> $DIR/comparison_to_empty.rs:13:13 | LL | let _ = v == []; | ^^^^^^^ help: using `is_empty` is clearer and more explicit: `v.is_empty()` error: comparison to empty slice - --> $DIR/comparison_to_empty.rs:13:13 + --> $DIR/comparison_to_empty.rs:14:13 | LL | let _ = v != []; | ^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!v.is_empty()` diff --git a/tests/ui/crashes/auxiliary/proc_macro_crash.rs b/tests/ui/crashes/auxiliary/proc_macro_crash.rs index 5ff2af7cd825..92f85a27d7db 100644 --- a/tests/ui/crashes/auxiliary/proc_macro_crash.rs +++ b/tests/ui/crashes/auxiliary/proc_macro_crash.rs @@ -1,13 +1,15 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +<<<<<<< HEAD +======= +//@compile-flags: --emit=link +//@no-prefer-dynamic // ^ compiletest by default builds all aux files as dylibs, but we don't want that for proc-macro // crates. If we don't set this, compiletest will override the `crate_type` attribute below and // compile this as dylib. Removing this then causes the test to fail because a `dylib` crate can't // contain a proc-macro. +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(repr128)] #![allow(incomplete_features)] -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/crashes/ice-10148.rs b/tests/ui/crashes/ice-10148.rs index 1ab3570c907c..70b85bdc4b6e 100644 --- a/tests/ui/crashes/ice-10148.rs +++ b/tests/ui/crashes/ice-10148.rs @@ -1,4 +1,8 @@ -// aux-build:../../auxiliary/proc_macros.rs +<<<<<<< HEAD +//@aux-build:../auxiliary/proc_macros.rs:proc-macro +======= +//@aux-build:../../auxiliary/proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) extern crate proc_macros; diff --git a/tests/ui/crashes/ice-10645.rs b/tests/ui/crashes/ice-10645.rs new file mode 100644 index 000000000000..35b2eb549811 --- /dev/null +++ b/tests/ui/crashes/ice-10645.rs @@ -0,0 +1,11 @@ +<<<<<<< HEAD +//@compile-flags: --cap-lints=warn +======= +// compile-flags: --cap-lints=warn +>>>>>>> e4f5d83fa (Fixed formatting.) +// https://github.com/rust-lang/rust-clippy/issues/10645 + +#![warn(clippy::future_not_send)] +pub async fn bar<'a, T: 'a>(_: T) {} + +fn main() {} diff --git a/tests/ui/crashes/ice-10645.stderr b/tests/ui/crashes/ice-10645.stderr new file mode 100644 index 000000000000..f11150f2b597 --- /dev/null +++ b/tests/ui/crashes/ice-10645.stderr @@ -0,0 +1,24 @@ +<<<<<<< HEAD +warning: future cannot be sent between threads safely +======= +error: future cannot be sent between threads safely +>>>>>>> e4f5d83fa (Fixed formatting.) + --> $DIR/ice-10645.rs:5:35 + | +LL | pub async fn bar<'a, T: 'a>(_: T) {} + | ^ future returned by `bar` is not `Send` + | +note: captured value is not `Send` + --> $DIR/ice-10645.rs:5:29 + | +LL | pub async fn bar<'a, T: 'a>(_: T) {} + | ^ has type `T` which is not `Send` + = note: `T` doesn't implement `std::marker::Send` + = note: `-D clippy::future-not-send` implied by `-D warnings` + +<<<<<<< HEAD +warning: 1 warning emitted +======= +error: aborting due to previous error +>>>>>>> e4f5d83fa (Fixed formatting.) + diff --git a/tests/ui/crashes/ice-10912.rs b/tests/ui/crashes/ice-10912.rs new file mode 100644 index 000000000000..69d7f2f395ff --- /dev/null +++ b/tests/ui/crashes/ice-10912.rs @@ -0,0 +1,4 @@ +#![warn(clippy::unreadable_literal)] +fn f2() -> impl Sized { && 3.14159265358979323846E } + +fn main() {} diff --git a/tests/ui/crashes/ice-10912.stderr b/tests/ui/crashes/ice-10912.stderr new file mode 100644 index 000000000000..a74ce731577d --- /dev/null +++ b/tests/ui/crashes/ice-10912.stderr @@ -0,0 +1,16 @@ +error: expected at least one digit in exponent + --> $DIR/ice-10912.rs:2:28 + | +LL | fn f2() -> impl Sized { && 3.14159265358979323846E } + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: long literal lacking separators + --> $DIR/ice-10912.rs:2:28 + | +LL | fn f2() -> impl Sized { && 3.14159265358979323846E } + | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider: `3.141_592_653_589_793_238_46` + | + = note: `-D clippy::unreadable-literal` implied by `-D warnings` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/crashes/ice-1782.rs b/tests/ui/crashes/ice-1782.rs index 81af88962a64..19ab03418eed 100644 --- a/tests/ui/crashes/ice-1782.rs +++ b/tests/ui/crashes/ice-1782.rs @@ -1,4 +1,5 @@ #![allow(dead_code, unused_variables)] +#![allow(clippy::unnecessary_cast)] /// Should not trigger an ICE in `SpanlessEq` / `consts::constant` /// diff --git a/tests/ui/crashes/ice-2774.stderr b/tests/ui/crashes/ice-2774.stderr index c5ea0b16d1be..a166ccb3ee8f 100644 --- a/tests/ui/crashes/ice-2774.stderr +++ b/tests/ui/crashes/ice-2774.stderr @@ -1,8 +1,8 @@ error: the following explicit lifetimes could be elided: 'a - --> $DIR/ice-2774.rs:15:1 + --> $DIR/ice-2774.rs:15:28 | LL | pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | = note: `-D clippy::needless-lifetimes` implied by `-D warnings` help: elide the lifetimes diff --git a/tests/ui/crashes/ice-3462.rs b/tests/ui/crashes/ice-3462.rs index b402052882ad..21cd9d337cdd 100644 --- a/tests/ui/crashes/ice-3462.rs +++ b/tests/ui/crashes/ice-3462.rs @@ -1,5 +1,5 @@ #![warn(clippy::all)] -#![allow(clippy::disallowed_names, clippy::equatable_if_let)] +#![allow(clippy::disallowed_names, clippy::equatable_if_let, clippy::needless_if)] #![allow(unused)] /// Test for https://github.com/rust-lang/rust-clippy/issues/3462 diff --git a/tests/ui/crashes/ice-3741.rs b/tests/ui/crashes/ice-3741.rs index 1253ddcfaeb3..ac4ed77c2d62 100644 --- a/tests/ui/crashes/ice-3741.rs +++ b/tests/ui/crashes/ice-3741.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macro_crash.rs +<<<<<<< HEAD +//@aux-build:proc_macro_crash.rs:proc-macro +======= +//@aux-build:proc_macro_crash.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::suspicious_else_formatting)] diff --git a/tests/ui/crashes/ice-4968.rs b/tests/ui/crashes/ice-4968.rs index e0510d942c20..87364122a356 100644 --- a/tests/ui/crashes/ice-4968.rs +++ b/tests/ui/crashes/ice-4968.rs @@ -1,5 +1,8 @@ -// check-pass +<<<<<<< HEAD +======= +//@check-pass +>>>>>>> e4f5d83fa (Fixed formatting.) // Test for https://github.com/rust-lang/rust-clippy/issues/4968 #![warn(clippy::unsound_collection_transmute)] diff --git a/tests/ui/crashes/ice-5207.rs b/tests/ui/crashes/ice-5207.rs index f463f78a99ab..6d7d864fe1a5 100644 --- a/tests/ui/crashes/ice-5207.rs +++ b/tests/ui/crashes/ice-5207.rs @@ -1,5 +1,16 @@ +<<<<<<< HEAD +<<<<<<< HEAD // Regression test for https://github.com/rust-lang/rust-clippy/issues/5207 +======= +// compile-flags: --cap-lints=warn +// ^ for https://github.com/rust-lang/rust-clippy/issues/10645 +// Regression test for https://github.com/rust-lang/rust-clippy/issues/5207 +#![warn(clippy::future_not_send)] +>>>>>>> 1dfc231b1 (clippy: add test for https://github.com/rust-lang/rust-clippy/issues/10645) +======= +// Regression test for https://github.com/rust-lang/rust-clippy/issues/5207 +>>>>>>> 572eecd26 (split test into 2) pub async fn bar<'a, T: 'a>(_: T) {} fn main() {} diff --git a/tests/ui/crashes/ice-5497.rs b/tests/ui/crashes/ice-5497.rs index 0769bce5fc80..f77f691c1927 100644 --- a/tests/ui/crashes/ice-5497.rs +++ b/tests/ui/crashes/ice-5497.rs @@ -7,5 +7,5 @@ pub trait Foo { impl Foo for Vec { const OOB: i32 = [1][1] + T::OOB; - //~^ ERROR operation will panic + //~^ ERROR: operation will panic } diff --git a/tests/ui/crashes/ice-5579.rs b/tests/ui/crashes/ice-5579.rs index e1842c73f0e3..8ab36bbf93cb 100644 --- a/tests/ui/crashes/ice-5579.rs +++ b/tests/ui/crashes/ice-5579.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unnecessary_literal_unwrap)] + trait IsErr { fn is_err(&self, err: &str) -> bool; } diff --git a/tests/ui/crashes/ice-6250.stderr b/tests/ui/crashes/ice-6250.stderr index 4506d1550bd4..97390af3e89e 100644 --- a/tests/ui/crashes/ice-6250.stderr +++ b/tests/ui/crashes/ice-6250.stderr @@ -1,9 +1,3 @@ -error[E0601]: `main` function not found in crate `ice_6250` - --> $DIR/ice-6250.rs:16:2 - | -LL | } - | ^ consider adding a `main` function to `$DIR/ice-6250.rs` - error[E0308]: mismatched types --> $DIR/ice-6250.rs:12:14 | @@ -12,11 +6,6 @@ LL | for reference in vec![1, 2, 3] { ... LL | Some(reference) = cache.data.get(key) { | ^^^^^^^^^ expected integer, found `&i32` - | -help: consider dereferencing the borrow - | -LL | Some(*reference) = cache.data.get(key) { - | + error[E0308]: mismatched types --> $DIR/ice-6250.rs:12:9 @@ -29,7 +18,6 @@ help: consider adding `let` LL | let Some(reference) = cache.data.get(key) { | +++ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0308, E0601. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/crashes/ice-6251.stderr b/tests/ui/crashes/ice-6251.stderr index 8da2965c6351..68a5766c90c0 100644 --- a/tests/ui/crashes/ice-6251.stderr +++ b/tests/ui/crashes/ice-6251.stderr @@ -1,9 +1,3 @@ -error[E0601]: `main` function not found in crate `ice_6251` - --> $DIR/ice-6251.rs:6:2 - | -LL | } - | ^ consider adding a `main` function to `$DIR/ice-6251.rs` - error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/ice-6251.rs:4:45 | @@ -35,7 +29,7 @@ LL | fn bug() -> impl Iterator { = note: expected type `usize` found closure `[closure@$DIR/ice-6251.rs:4:44: 4:53]` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0277, E0308, E0601. +Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/crashes/ice-6252.stderr b/tests/ui/crashes/ice-6252.stderr index efdd56dd47d3..759649712bcd 100644 --- a/tests/ui/crashes/ice-6252.stderr +++ b/tests/ui/crashes/ice-6252.stderr @@ -6,11 +6,26 @@ LL | _n: PhantomData, | help: consider importing one of these items | -LL | use core::marker::PhantomData; - | -LL | use serde::__private::PhantomData; - | -LL | use std::marker::PhantomData; +LL + use core::marker::PhantomData; +<<<<<<< HEAD +<<<<<<< HEAD + | +LL + use serde::__private::PhantomData; + | +LL + use std::marker::PhantomData; +======= +LL | trait TypeVal { +======= +>>>>>>> 4680aa2fd (Special-case item attributes in the suggestion output) + | +LL + use serde::__private::PhantomData; + | +LL + use std::marker::PhantomData; +<<<<<<< HEAD +LL | trait TypeVal { +>>>>>>> 7a0fb902b (Tweak output for 'add line' suggestion) +======= +>>>>>>> 4680aa2fd (Special-case item attributes in the suggestion output) | error[E0412]: cannot find type `VAL` in this scope diff --git a/tests/ui/crashes/ice-6255.rs b/tests/ui/crashes/ice-6255.rs index ccde6aa2b0f7..b6555ac5c407 100644 --- a/tests/ui/crashes/ice-6255.rs +++ b/tests/ui/crashes/ice-6255.rs @@ -4,7 +4,6 @@ macro_rules! define_other_core { ( ) => { extern crate std as core; - //~^ ERROR macro-expanded `extern crate` items cannot shadow names passed with `--extern` }; } @@ -13,3 +12,4 @@ fn main() { } define_other_core!(); +//~^ ERROR: macro-expanded `extern crate` items cannot shadow names passed with `--extern` diff --git a/tests/ui/crashes/ice-6256.rs b/tests/ui/crashes/ice-6256.rs index f9ee3e058c11..1d336b3cdc0c 100644 --- a/tests/ui/crashes/ice-6256.rs +++ b/tests/ui/crashes/ice-6256.rs @@ -10,6 +10,6 @@ impl dyn TT { #[rustfmt::skip] fn main() { - let f = |x: &dyn TT| x.func(); //[default]~ ERROR: mismatched types - //[nll]~^ ERROR: borrowed data escapes outside of closure + let f = |x: &dyn TT| x.func(); + //~^ ERROR: borrowed data escapes outside of closure } diff --git a/tests/ui/crashes/ice-6256.stderr b/tests/ui/crashes/ice-6256.stderr index 9cfcccf1e3cd..671933157c80 100644 --- a/tests/ui/crashes/ice-6256.stderr +++ b/tests/ui/crashes/ice-6256.stderr @@ -1,7 +1,7 @@ error[E0521]: borrowed data escapes outside of closure --> $DIR/ice-6256.rs:13:26 | -LL | let f = |x: &dyn TT| x.func(); //[default]~ ERROR: mismatched types +LL | let f = |x: &dyn TT| x.func(); | - - ^^^^^^^^ | | | | | | | `x` escapes the closure body here diff --git a/tests/ui/crashes/ice-7169.rs b/tests/ui/crashes/ice-7169.rs index 82095febc194..b203252f0a14 100644 --- a/tests/ui/crashes/ice-7169.rs +++ b/tests/ui/crashes/ice-7169.rs @@ -1,3 +1,5 @@ +#![allow(clippy::needless_if)] + #[derive(Default)] struct A { a: Vec>, diff --git a/tests/ui/crashes/ice-7169.stderr b/tests/ui/crashes/ice-7169.stderr index 5a9cd32380a1..0cd02851640e 100644 --- a/tests/ui/crashes/ice-7169.stderr +++ b/tests/ui/crashes/ice-7169.stderr @@ -1,8 +1,8 @@ error: redundant pattern matching, consider using `is_ok()` - --> $DIR/ice-7169.rs:8:12 + --> $DIR/ice-7169.rs:10:12 | LL | if let Ok(_) = Ok::<_, ()>(A::::default()) {} - | -------^^^^^-------------------------------------- help: try this: `if Ok::<_, ()>(A::::default()).is_ok()` + | -------^^^^^-------------------------------------- help: try: `if Ok::<_, ()>(A::::default()).is_ok()` | = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` diff --git a/tests/ui/crashes/ice-7272.rs b/tests/ui/crashes/ice-7272.rs index 57ab6ca14f86..e949038c8d0b 100644 --- a/tests/ui/crashes/ice-7272.rs +++ b/tests/ui/crashes/ice-7272.rs @@ -1,4 +1,4 @@ -// aux-build:ice-7272-aux.rs +//@aux-build:ice-7272-aux.rs #![allow(clippy::no_effect)] diff --git a/tests/ui/crashes/ice-7410.rs b/tests/ui/crashes/ice-7410.rs index 85fa42103219..d4efa0fcce82 100644 --- a/tests/ui/crashes/ice-7410.rs +++ b/tests/ui/crashes/ice-7410.rs @@ -1,11 +1,17 @@ -// compile-flags: -Clink-arg=-nostartfiles -// ignore-macos -// ignore-windows +//@compile-flags: -Clink-arg=-nostartfiles +<<<<<<< HEAD +//@ignore-target-apple +//@ignore-target-windows +======= +//@ignore-macos +//@ignore-windows +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(lang_items, start, libc)] #![no_std] #![allow(clippy::if_same_then_else)] #![allow(clippy::redundant_pattern_matching)] +#![allow(clippy::needless_else)] use core::panic::PanicInfo; diff --git a/tests/ui/crashes/ice-8250.stderr b/tests/ui/crashes/ice-8250.stderr index 8ed8f3b3a064..e6f3644ef34f 100644 --- a/tests/ui/crashes/ice-8250.stderr +++ b/tests/ui/crashes/ice-8250.stderr @@ -2,7 +2,7 @@ error: unnecessary use of `splitn` --> $DIR/ice-8250.rs:2:13 | LL | let _ = s[1..].splitn(2, '.').next()?; - | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `s[1..].split('.')` + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `s[1..].split('.')` | = note: `-D clippy::needless-splitn` implied by `-D warnings` diff --git a/tests/ui/crashes/ice-8681.rs b/tests/ui/crashes/ice-8681.rs index ee14f011f631..607b9caa3249 100644 --- a/tests/ui/crashes/ice-8681.rs +++ b/tests/ui/crashes/ice-8681.rs @@ -1,4 +1,4 @@ -// aux-build: ice-8681-aux.rs +//@aux-build: ice-8681-aux.rs #![warn(clippy::undocumented_unsafe_blocks)] diff --git a/tests/ui/crashes/ice-9445.stderr b/tests/ui/crashes/ice-9445.stderr new file mode 100644 index 000000000000..a59d098e5ac0 --- /dev/null +++ b/tests/ui/crashes/ice-9445.stderr @@ -0,0 +1,12 @@ +error: a `const` item should never be interior mutable + --> $DIR/ice-9445.rs:1:1 + | +LL | const UNINIT: core::mem::MaybeUninit> = core::mem::MaybeUninit::uninit(); + | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | make this a static item (maybe with lazy_static) + | + = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/tests/ui/crashes/ice-96721.rs b/tests/ui/crashes/ice-96721.rs index 4b3fb7640108..ca68ba3d03a5 100644 --- a/tests/ui/crashes/ice-96721.rs +++ b/tests/ui/crashes/ice-96721.rs @@ -4,7 +4,7 @@ macro_rules! foo { }; } -#[path = foo!()] //~ ERROR malformed `path` attribute +#[path = foo!()] //~ ERROR: malformed `path` attribute mod abc {} fn main() {} diff --git a/tests/ui/crashes/ice-96721.stderr b/tests/ui/crashes/ice-96721.stderr index 78c567b8e772..712bd14c685f 100644 --- a/tests/ui/crashes/ice-96721.stderr +++ b/tests/ui/crashes/ice-96721.stderr @@ -1,7 +1,7 @@ error: malformed `path` attribute input --> $DIR/ice-96721.rs:7:1 | -LL | #[path = foo!()] //~ ERROR malformed `path` attribute +LL | #[path = foo!()] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[path = "file"]` error: aborting due to previous error diff --git a/tests/ui/crashes/ice_exacte_size.rs b/tests/ui/crashes/ice_exact_size.rs similarity index 100% rename from tests/ui/crashes/ice_exacte_size.rs rename to tests/ui/crashes/ice_exact_size.rs diff --git a/tests/ui/crashes/mut_mut_macro.rs b/tests/ui/crashes/mut_mut_macro.rs index a238e7896fc6..92821b6ecbba 100644 --- a/tests/ui/crashes/mut_mut_macro.rs +++ b/tests/ui/crashes/mut_mut_macro.rs @@ -1,4 +1,4 @@ -#![deny(clippy::mut_mut, clippy::zero_ptr, clippy::cmp_nan)] +#![deny(clippy::mut_mut, clippy::zero_ptr)] #![allow(dead_code)] // FIXME: compiletest + extern crates doesn't work together. To make this test work, it would need @@ -8,13 +8,12 @@ // extern crate lazy_static; // use std::collections::HashMap; -/// ensure that we don't suggest `is_nan` and `is_null` inside constants +/// ensure that we don't suggest `is_null` inside constants /// FIXME: once const fn is stable, suggest these functions again in constants const BAA: *const i32 = 0 as *const i32; static mut BAR: *const i32 = BAA; static mut FOO: *const i32 = 0 as *const i32; -static mut BUH: bool = 42.0 < f32::NAN; #[allow(unused_variables, unused_mut)] fn main() { diff --git a/tests/ui/crashes/needless_lifetimes_impl_trait.stderr b/tests/ui/crashes/needless_lifetimes_impl_trait.stderr index 0b0e0ad2684a..37484f5ebd70 100644 --- a/tests/ui/crashes/needless_lifetimes_impl_trait.stderr +++ b/tests/ui/crashes/needless_lifetimes_impl_trait.stderr @@ -1,8 +1,8 @@ error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes_impl_trait.rs:15:5 + --> $DIR/needless_lifetimes_impl_trait.rs:15:12 | LL | fn baz<'a>(&'a self) -> impl Foo + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | note: the lint level is defined here --> $DIR/needless_lifetimes_impl_trait.rs:1:9 diff --git a/tests/ui/crate_in_macro_def.fixed b/tests/ui/crate_in_macro_def.fixed index 9fc594be311e..12a7b9470b31 100644 --- a/tests/ui/crate_in_macro_def.fixed +++ b/tests/ui/crate_in_macro_def.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::crate_in_macro_def)] mod hygienic { diff --git a/tests/ui/crate_in_macro_def.rs b/tests/ui/crate_in_macro_def.rs index ac456108e4ab..a1a9eabf639b 100644 --- a/tests/ui/crate_in_macro_def.rs +++ b/tests/ui/crate_in_macro_def.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::crate_in_macro_def)] mod hygienic { diff --git a/tests/ui/crate_level_checks/entrypoint_recursion.rs b/tests/ui/crate_level_checks/entrypoint_recursion.rs index 1b3bcece6f1e..3a3b42c8d729 100644 --- a/tests/ui/crate_level_checks/entrypoint_recursion.rs +++ b/tests/ui/crate_level_checks/entrypoint_recursion.rs @@ -1,4 +1,8 @@ -// ignore-macos +<<<<<<< HEAD +//@ignore-target-apple +======= +//@ignore-macos +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(rustc_attrs)] diff --git a/tests/ui/crate_level_checks/entrypoint_recursion.stderr b/tests/ui/crate_level_checks/entrypoint_recursion.stderr deleted file mode 100644 index 3d79a115cb30..000000000000 --- a/tests/ui/crate_level_checks/entrypoint_recursion.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: recursing into entrypoint `a` - --> $DIR/entrypoint_recursion.rs:10:5 - | -LL | a(); - | ^ - | - = help: consider using another function for this recursion - = note: `-D clippy::main-recursion` implied by `-D warnings` - -error: aborting due to previous error - diff --git a/tests/ui/crate_level_checks/no_std_main_recursion.rs b/tests/ui/crate_level_checks/no_std_main_recursion.rs index e1c9fe30a9df..f5e449994e07 100644 --- a/tests/ui/crate_level_checks/no_std_main_recursion.rs +++ b/tests/ui/crate_level_checks/no_std_main_recursion.rs @@ -1,5 +1,9 @@ -// compile-flags: -Clink-arg=-nostartfiles -// ignore-macos +//@compile-flags: -Clink-arg=-nostartfiles +<<<<<<< HEAD +//@ignore-target-apple +======= +//@ignore-macos +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(lang_items, start, libc)] #![no_std] diff --git a/tests/ui/create_dir.fixed b/tests/ui/create_dir.fixed index 8ed53a56ac04..5de3e9fea0bc 100644 --- a/tests/ui/create_dir.fixed +++ b/tests/ui/create_dir.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_must_use)] #![warn(clippy::create_dir)] diff --git a/tests/ui/create_dir.rs b/tests/ui/create_dir.rs index 19c8fc24ba23..d375bfb4a688 100644 --- a/tests/ui/create_dir.rs +++ b/tests/ui/create_dir.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_must_use)] #![warn(clippy::create_dir)] diff --git a/tests/ui/dbg_macro.rs b/tests/ui/dbg_macro.rs index 25294e8c766f..e04d4b222302 100644 --- a/tests/ui/dbg_macro.rs +++ b/tests/ui/dbg_macro.rs @@ -1,9 +1,13 @@ -// compile-flags: --test +<<<<<<< HEAD +======= +//@compile-flags: --test +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::dbg_macro)] fn foo(n: u32) -> u32 { if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } } +fn bar(_: ()) {} fn factorial(n: u32) -> u32 { if dbg!(n <= 1) { @@ -21,6 +25,50 @@ fn main() { dbg!(1, 2, 3, 4, 5); } +fn issue9914() { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) + macro_rules! foo { + ($x:expr) => { + $x; + }; + } + macro_rules! foo2 { + ($x:expr) => { + $x; + }; + } + macro_rules! expand_to_dbg { + () => { + dbg!(); + }; + } + +<<<<<<< HEAD +======= +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) + dbg!(); + #[allow(clippy::let_unit_value)] + let _ = dbg!(); + bar(dbg!()); +<<<<<<< HEAD +<<<<<<< HEAD + foo!(dbg!()); + foo2!(foo!(dbg!())); + expand_to_dbg!(); +======= +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= + foo!(dbg!()); + foo2!(foo!(dbg!())); + expand_to_dbg!(); +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +} + mod issue7274 { trait Thing<'b> { fn foo(&self); diff --git a/tests/ui/dbg_macro.stderr b/tests/ui/dbg_macro.stderr index ddb5f1342e99..80ce6a29c5cb 100644 --- a/tests/ui/dbg_macro.stderr +++ b/tests/ui/dbg_macro.stderr @@ -1,5 +1,5 @@ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:5:22 + --> $DIR/dbg_macro.rs:4:22 | LL | if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -99,7 +99,127 @@ LL | (1, 2, 3, 4, 5); | ~~~~~~~~~~~~~~~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:41:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/dbg_macro.rs:41:5 +======= + --> $DIR/dbg_macro.rs:26:5 +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= + --> $DIR/dbg_macro.rs:42:5 +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +======= + --> $DIR/dbg_macro.rs:41:5 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | dbg!(); + | ^^^^^^^ + | +help: remove the invocation before committing it to a version control system + | +LL - dbg!(); +LL + + | + +error: the `dbg!` macro is intended as a debugging tool +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/dbg_macro.rs:43:13 +======= + --> $DIR/dbg_macro.rs:28:13 +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= + --> $DIR/dbg_macro.rs:44:13 +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +======= + --> $DIR/dbg_macro.rs:43:13 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | let _ = dbg!(); + | ^^^^^^ + | +help: remove the invocation before committing it to a version control system + | +LL | let _ = (); + | ~~ + +error: the `dbg!` macro is intended as a debugging tool +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/dbg_macro.rs:44:9 +======= + --> $DIR/dbg_macro.rs:29:9 +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= + --> $DIR/dbg_macro.rs:45:9 +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +======= + --> $DIR/dbg_macro.rs:44:9 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | bar(dbg!()); + | ^^^^^^ + | +help: remove the invocation before committing it to a version control system + | +LL | bar(()); + | ~~ + +error: the `dbg!` macro is intended as a debugging tool +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/dbg_macro.rs:45:10 +======= + --> $DIR/dbg_macro.rs:46:10 +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +======= + --> $DIR/dbg_macro.rs:45:10 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | foo!(dbg!()); + | ^^^^^^ + | +help: remove the invocation before committing it to a version control system + | +LL | foo!(()); + | ~~ + +error: the `dbg!` macro is intended as a debugging tool +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/dbg_macro.rs:46:16 +======= + --> $DIR/dbg_macro.rs:47:16 +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +======= + --> $DIR/dbg_macro.rs:46:16 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | foo2!(foo!(dbg!())); + | ^^^^^^ + | +help: remove the invocation before committing it to a version control system + | +LL | foo2!(foo!(())); + | ~~ + +error: the `dbg!` macro is intended as a debugging tool +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/dbg_macro.rs:67:9 +======= + --> $DIR/dbg_macro.rs:49:9 +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= + --> $DIR/dbg_macro.rs:68:9 +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +======= + --> $DIR/dbg_macro.rs:67:9 +>>>>>>> 5bd97ac17 (Update tests) | LL | dbg!(2); | ^^^^^^^ @@ -110,7 +230,19 @@ LL | 2; | ~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:47:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/dbg_macro.rs:73:5 +======= + --> $DIR/dbg_macro.rs:55:5 +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= + --> $DIR/dbg_macro.rs:74:5 +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +======= + --> $DIR/dbg_macro.rs:73:5 +>>>>>>> 5bd97ac17 (Update tests) | LL | dbg!(1); | ^^^^^^^ @@ -121,7 +253,19 @@ LL | 1; | ~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:52:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/dbg_macro.rs:78:5 +======= + --> $DIR/dbg_macro.rs:60:5 +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= + --> $DIR/dbg_macro.rs:79:5 +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +======= + --> $DIR/dbg_macro.rs:78:5 +>>>>>>> 5bd97ac17 (Update tests) | LL | dbg!(1); | ^^^^^^^ @@ -132,7 +276,19 @@ LL | 1; | ~ error: the `dbg!` macro is intended as a debugging tool - --> $DIR/dbg_macro.rs:58:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/dbg_macro.rs:84:9 +======= + --> $DIR/dbg_macro.rs:66:9 +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= + --> $DIR/dbg_macro.rs:85:9 +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) +======= + --> $DIR/dbg_macro.rs:84:9 +>>>>>>> 5bd97ac17 (Update tests) | LL | dbg!(1); | ^^^^^^^ @@ -142,5 +298,13 @@ help: remove the invocation before committing it to a version control system LL | 1; | ~ -error: aborting due to 13 previous errors +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 18 previous errors +======= +error: aborting due to 16 previous errors +>>>>>>> cc607fe32 (don't remove `dbg!` in arbitrary expressions) +======= +error: aborting due to 18 previous errors +>>>>>>> f0be0ee1a (handle nested macros and add tests for them) diff --git a/tests/ui/decimal_literal_representation.fixed b/tests/ui/decimal_literal_representation.fixed index de391465125c..a6eb8c214578 100644 --- a/tests/ui/decimal_literal_representation.fixed +++ b/tests/ui/decimal_literal_representation.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::decimal_literal_representation)] #[allow(unused_variables)] diff --git a/tests/ui/decimal_literal_representation.rs b/tests/ui/decimal_literal_representation.rs index 55d07698e7e5..7c666d6d7a69 100644 --- a/tests/ui/decimal_literal_representation.rs +++ b/tests/ui/decimal_literal_representation.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::decimal_literal_representation)] #[allow(unused_variables)] diff --git a/tests/ui/declare_interior_mutable_const/enums.rs b/tests/ui/declare_interior_mutable_const/enums.rs index f44518694b89..a88bf7b21b8b 100644 --- a/tests/ui/declare_interior_mutable_const/enums.rs +++ b/tests/ui/declare_interior_mutable_const/enums.rs @@ -9,7 +9,7 @@ enum OptionalCell { } // a constant with enums should be linted only when the used variant is unfrozen (#3962). -const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(true)); //~ ERROR interior mutable +const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(true)); //~ ERROR: interior mutable const FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen; const fn unfrozen_variant() -> OptionalCell { @@ -20,7 +20,7 @@ const fn frozen_variant() -> OptionalCell { OptionalCell::Frozen } -const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); //~ ERROR interior mutable +const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); //~ ERROR: interior mutable const FROZEN_VARIANT_FROM_FN: OptionalCell = frozen_variant(); enum NestedInnermost { @@ -43,10 +43,11 @@ struct NestedOutermost { // a constant with enums should be linted according to its value, no matter how structs involve. const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost { + //~^ ERROR: interior mutable outer: NestedOuter::NestedInner(NestedInner { inner: NestedInnermost::Unfrozen(AtomicUsize::new(2)), }), -}; //~ ERROR interior mutable +}; const NESTED_FROZEN_VARIANT: NestedOutermost = NestedOutermost { outer: NestedOuter::NestedInner(NestedInner { inner: NestedInnermost::Frozen, @@ -56,11 +57,11 @@ const NESTED_FROZEN_VARIANT: NestedOutermost = NestedOutermost { trait AssocConsts { // When there's no default value, lint it only according to its type. // Further details are on the corresponding code (`NonCopyConst::check_trait_item`). - const TO_BE_UNFROZEN_VARIANT: OptionalCell; //~ ERROR interior mutable - const TO_BE_FROZEN_VARIANT: OptionalCell; //~ ERROR interior mutable + const TO_BE_UNFROZEN_VARIANT: OptionalCell; //~ ERROR: interior mutable + const TO_BE_FROZEN_VARIANT: OptionalCell; //~ ERROR: interior mutable // Lint default values accordingly. - const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); //~ ERROR interior mutable + const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); //~ ERROR: interior mutable const DEFAULTED_ON_FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen; } @@ -86,7 +87,7 @@ trait AssocTypes { impl AssocTypes for u64 { type ToBeUnfrozen = AtomicUsize; - const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); //~ ERROR interior mutable + const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); //~ ERROR: interior mutable const TO_BE_FROZEN_VARIANT: Option = None; } @@ -98,25 +99,25 @@ enum BothOfCellAndGeneric { } impl BothOfCellAndGeneric { - const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); //~ ERROR interior mutable + const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); //~ ERROR: interior mutable // This is a false positive. The argument about this is on `is_value_unfrozen_raw` - const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR interior mutable + const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR: interior mutable const FROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Frozen(5); // This is what is likely to be a false negative when one tries to fix // the `GENERIC_VARIANT` false positive. - const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); //~ ERROR interior mutable + const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); //~ ERROR: interior mutable } // associated types here is basically the same as the one above. trait BothOfCellAndGenericWithAssocType { type AssocType; - const UNFROZEN_VARIANT: BothOfCellAndGeneric = - BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); //~ ERROR interior mutable - const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR interior mutable + const UNFROZEN_VARIANT: BothOfCellAndGeneric = //~ ERROR: interior mutable + BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); + const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR: interior mutable const FROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Frozen(5); } diff --git a/tests/ui/declare_interior_mutable_const/enums.stderr b/tests/ui/declare_interior_mutable_const/enums.stderr index 84198d546157..6070df749ca9 100644 --- a/tests/ui/declare_interior_mutable_const/enums.stderr +++ b/tests/ui/declare_interior_mutable_const/enums.stderr @@ -1,7 +1,7 @@ error: a `const` item should never be interior mutable --> $DIR/enums.rs:12:1 | -LL | const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(true)); //~ ERROR interior mutable +LL | const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(true)); | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | make this a static item (maybe with lazy_static) @@ -11,7 +11,7 @@ LL | const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(tru error: a `const` item should never be interior mutable --> $DIR/enums.rs:23:1 | -LL | const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); //~ ERROR interior mutable +LL | const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | make this a static item (maybe with lazy_static) @@ -24,65 +24,66 @@ LL | const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost { | | | _make this a static item (maybe with lazy_static) | | +LL | | LL | | outer: NestedOuter::NestedInner(NestedInner { LL | | inner: NestedInnermost::Unfrozen(AtomicUsize::new(2)), LL | | }), -LL | | }; //~ ERROR interior mutable +LL | | }; | |__^ error: a `const` item should never be interior mutable - --> $DIR/enums.rs:59:5 + --> $DIR/enums.rs:60:5 | -LL | const TO_BE_UNFROZEN_VARIANT: OptionalCell; //~ ERROR interior mutable +LL | const TO_BE_UNFROZEN_VARIANT: OptionalCell; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable - --> $DIR/enums.rs:60:5 + --> $DIR/enums.rs:61:5 | -LL | const TO_BE_FROZEN_VARIANT: OptionalCell; //~ ERROR interior mutable +LL | const TO_BE_FROZEN_VARIANT: OptionalCell; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable - --> $DIR/enums.rs:63:5 + --> $DIR/enums.rs:64:5 | -LL | const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); //~ ERROR interior mutable +LL | const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable - --> $DIR/enums.rs:89:5 + --> $DIR/enums.rs:90:5 | -LL | const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); //~ ERROR interior mutable +LL | const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable - --> $DIR/enums.rs:101:5 + --> $DIR/enums.rs:102:5 | -LL | const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); //~ ERROR interior mut... +LL | const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable - --> $DIR/enums.rs:104:5 + --> $DIR/enums.rs:105:5 | -LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR interior mutable +LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable - --> $DIR/enums.rs:110:5 + --> $DIR/enums.rs:111:5 | -LL | const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); //~ ERROR interior mutable +LL | const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable - --> $DIR/enums.rs:117:5 + --> $DIR/enums.rs:118:5 | LL | / const UNFROZEN_VARIANT: BothOfCellAndGeneric = -LL | | BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); //~ ERROR interior mutable +LL | | BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); | |____________________________________________________________________^ error: a `const` item should never be interior mutable - --> $DIR/enums.rs:119:5 + --> $DIR/enums.rs:120:5 | -LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); //~ ERROR interior mu... +LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 12 previous errors diff --git a/tests/ui/declare_interior_mutable_const/others.rs b/tests/ui/declare_interior_mutable_const/others.rs index 896596b56792..1cec2980652c 100644 --- a/tests/ui/declare_interior_mutable_const/others.rs +++ b/tests/ui/declare_interior_mutable_const/others.rs @@ -6,17 +6,17 @@ use std::fmt::Display; use std::sync::atomic::AtomicUsize; use std::sync::Once; -const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR interior mutable -const CELL: Cell = Cell::new(6); //~ ERROR interior mutable +const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR: interior mutable +const CELL: Cell = Cell::new(6); //~ ERROR: interior mutable const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec, u8) = ([ATOMIC], Vec::new(), 7); -//~^ ERROR interior mutable +//~^ ERROR: interior mutable macro_rules! declare_const { ($name:ident: $ty:ty = $e:expr) => { const $name: $ty = $e; }; } -declare_const!(_ONCE: Once = Once::new()); //~ ERROR interior mutable +declare_const!(_ONCE: Once = Once::new()); //~ ERROR: interior mutable // const ATOMIC_REF: &AtomicUsize = &AtomicUsize::new(7); // This will simply trigger E0492. @@ -24,12 +24,12 @@ const INTEGER: u8 = 8; const STRING: String = String::new(); const STR: &str = "012345"; const COW: Cow = Cow::Borrowed("abcdef"); -//^ note: a const item of Cow is used in the `postgres` package. +// note: a const item of Cow is used in the `postgres` package. const NO_ANN: &dyn Display = &70; static STATIC_TUPLE: (AtomicUsize, String) = (ATOMIC, STRING); -//^ there should be no lints on this line +// there should be no lints on the line above line mod issue_8493 { use std::cell::Cell; @@ -40,7 +40,7 @@ mod issue_8493 { macro_rules! issue_8493 { () => { - const _BAZ: Cell = Cell::new(0); //~ ERROR interior mutable + const _BAZ: Cell = Cell::new(0); static _FOOBAR: () = { thread_local! { static _VAR: Cell = const { Cell::new(0) }; @@ -49,7 +49,7 @@ mod issue_8493 { }; } - issue_8493!(); + issue_8493!(); //~ ERROR: interior mutable } fn main() {} diff --git a/tests/ui/declare_interior_mutable_const/others.stderr b/tests/ui/declare_interior_mutable_const/others.stderr index 1fd6d7322a76..0259f6a4a286 100644 --- a/tests/ui/declare_interior_mutable_const/others.stderr +++ b/tests/ui/declare_interior_mutable_const/others.stderr @@ -1,7 +1,7 @@ error: a `const` item should never be interior mutable --> $DIR/others.rs:9:1 | -LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR interior mutable +LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5); | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | make this a static item (maybe with lazy_static) @@ -11,7 +11,7 @@ LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR interior mutable error: a `const` item should never be interior mutable --> $DIR/others.rs:10:1 | -LL | const CELL: Cell = Cell::new(6); //~ ERROR interior mutable +LL | const CELL: Cell = Cell::new(6); | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | make this a static item (maybe with lazy_static) @@ -30,7 +30,7 @@ error: a `const` item should never be interior mutable LL | const $name: $ty = $e; | ^^^^^^^^^^^^^^^^^^^^^^ ... -LL | declare_const!(_ONCE: Once = Once::new()); //~ ERROR interior mutable +LL | declare_const!(_ONCE: Once = Once::new()); | ----------------------------------------- in this macro invocation | = note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -38,7 +38,7 @@ LL | declare_const!(_ONCE: Once = Once::new()); //~ ERROR interior mutable error: a `const` item should never be interior mutable --> $DIR/others.rs:43:13 | -LL | const _BAZ: Cell = Cell::new(0); //~ ERROR interior mutable +LL | const _BAZ: Cell = Cell::new(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | issue_8493!(); diff --git a/tests/ui/declare_interior_mutable_const/traits.rs b/tests/ui/declare_interior_mutable_const/traits.rs index 256a336db821..a6ccdd270798 100644 --- a/tests/ui/declare_interior_mutable_const/traits.rs +++ b/tests/ui/declare_interior_mutable_const/traits.rs @@ -12,10 +12,10 @@ macro_rules! declare_const { // a constant whose type is a concrete type should be linted at the definition site. trait ConcreteTypes { - const ATOMIC: AtomicUsize; //~ ERROR interior mutable + const ATOMIC: AtomicUsize; //~ ERROR: interior mutable const INTEGER: u64; const STRING: String; - declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR interior mutable + declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR: interior mutable } impl ConcreteTypes for u64 { @@ -40,7 +40,7 @@ trait GenericTypes { impl GenericTypes for u64 { const TO_REMAIN_GENERIC: T = T::DEFAULT; - const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); //~ ERROR interior mutable + const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); //~ ERROR: interior mutable } // a helper type used below @@ -65,8 +65,8 @@ impl AssocTypes for Vec { type ToBeGenericParam = T; const TO_BE_FROZEN: Self::ToBeFrozen = 12; - const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); //~ ERROR interior mutable - const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); //~ ERROR interior mutable + const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); //~ ERROR: interior mutable + const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); //~ ERROR: interior mutable const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper = Wrapper(T::DEFAULT); } @@ -85,7 +85,7 @@ where T: AssocTypesHelper, { const NOT_BOUNDED: T::NotToBeBounded; - const BOUNDED: T::ToBeBounded; //~ ERROR interior mutable + const BOUNDED: T::ToBeBounded; //~ ERROR: interior mutable } impl AssocTypesFromGenericParam for u64 @@ -113,8 +113,8 @@ impl SelfType for u64 { impl SelfType for AtomicUsize { // this (interior mutable `Self` const) exists in `parking_lot`. // `const_trait_impl` will replace it in the future, hopefully. - const SELF: Self = AtomicUsize::new(17); //~ ERROR interior mutable - const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); //~ ERROR interior mutable + const SELF: Self = AtomicUsize::new(17); //~ ERROR: interior mutable + const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); //~ ERROR: interior mutable } // Even though a constant contains a generic type, if it also have an interior mutable type, @@ -122,7 +122,7 @@ impl SelfType for AtomicUsize { trait BothOfCellAndGeneric { // this is a false negative in the current implementation. const DIRECT: Cell; - const INDIRECT: Cell<*const T>; //~ ERROR interior mutable + const INDIRECT: Cell<*const T>; //~ ERROR: interior mutable } impl BothOfCellAndGeneric for u64 { @@ -138,13 +138,13 @@ impl Local where T: ConstDefault + AssocTypesHelper, { - const ATOMIC: AtomicUsize = AtomicUsize::new(18); //~ ERROR interior mutable + const ATOMIC: AtomicUsize = AtomicUsize::new(18); //~ ERROR: interior mutable const COW: Cow<'static, str> = Cow::Borrowed("tuvwxy"); const GENERIC_TYPE: T = T::DEFAULT; const ASSOC_TYPE: T::NotToBeBounded = T::NOT_TO_BE_BOUNDED; - const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); //~ ERROR interior mutable + const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); //~ ERROR: interior mutable } fn main() {} diff --git a/tests/ui/declare_interior_mutable_const/traits.stderr b/tests/ui/declare_interior_mutable_const/traits.stderr index 7debe059ff4e..ef62919dfead 100644 --- a/tests/ui/declare_interior_mutable_const/traits.stderr +++ b/tests/ui/declare_interior_mutable_const/traits.stderr @@ -1,7 +1,7 @@ error: a `const` item should never be interior mutable --> $DIR/traits.rs:15:5 | -LL | const ATOMIC: AtomicUsize; //~ ERROR interior mutable +LL | const ATOMIC: AtomicUsize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings` @@ -12,7 +12,7 @@ error: a `const` item should never be interior mutable LL | const $name: $ty = $e; | ^^^^^^^^^^^^^^^^^^^^^^ ... -LL | declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR interior mutable +LL | declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); | ---------------------------------------------------------- in this macro invocation | = note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -20,55 +20,55 @@ LL | declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR i error: a `const` item should never be interior mutable --> $DIR/traits.rs:43:5 | -LL | const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); //~ ERROR interior mutable +LL | const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable --> $DIR/traits.rs:68:5 | -LL | const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); //~ ERROR interior mutable +LL | const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable --> $DIR/traits.rs:69:5 | -LL | const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); //~ ERROR interior mutable +LL | const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable --> $DIR/traits.rs:88:5 | -LL | const BOUNDED: T::ToBeBounded; //~ ERROR interior mutable +LL | const BOUNDED: T::ToBeBounded; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable --> $DIR/traits.rs:116:5 | -LL | const SELF: Self = AtomicUsize::new(17); //~ ERROR interior mutable +LL | const SELF: Self = AtomicUsize::new(17); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable --> $DIR/traits.rs:117:5 | -LL | const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); //~ ERROR interior mutable +LL | const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable --> $DIR/traits.rs:125:5 | -LL | const INDIRECT: Cell<*const T>; //~ ERROR interior mutable +LL | const INDIRECT: Cell<*const T>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable --> $DIR/traits.rs:141:5 | -LL | const ATOMIC: AtomicUsize = AtomicUsize::new(18); //~ ERROR interior mutable +LL | const ATOMIC: AtomicUsize = AtomicUsize::new(18); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable --> $DIR/traits.rs:147:5 | -LL | const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); //~ ERROR interior mutable +LL | const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 11 previous errors diff --git a/tests/ui/def_id_nocore.rs b/tests/ui/def_id_nocore.rs index 1af77d1a25b2..5a9b0c3bb492 100644 --- a/tests/ui/def_id_nocore.rs +++ b/tests/ui/def_id_nocore.rs @@ -1,4 +1,8 @@ -// ignore-macos +<<<<<<< HEAD +//@ignore-target-apple +======= +//@ignore-macos +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(no_core, lang_items, start)] #![no_core] diff --git a/tests/ui/default_constructed_unit_structs.fixed b/tests/ui/default_constructed_unit_structs.fixed new file mode 100644 index 000000000000..92a01c30fb9a --- /dev/null +++ b/tests/ui/default_constructed_unit_structs.fixed @@ -0,0 +1,214 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::default_constructed_unit_structs)] +use std::marker::PhantomData; + +#[derive(Default)] +struct UnitStruct; + +impl UnitStruct { + fn new() -> Self { + //should lint + Self + } +} + +#[derive(Default)] +struct TupleStruct(usize); + +impl TupleStruct { + fn new() -> Self { + // should not lint + Self(Default::default()) + } +} + +// no lint for derived impl +#[derive(Default)] +struct NormalStruct { + inner: PhantomData, +} + +struct NonDefaultStruct; + +impl NonDefaultStruct { + fn default() -> Self { + Self + } +} + +#[derive(Default)] +enum SomeEnum { + #[default] + Unit, + Tuple(UnitStruct), + Struct { + inner: usize, + }, +} + +impl NormalStruct { + fn new() -> Self { + // should lint + Self { + inner: PhantomData, + } + } + + fn new2() -> Self { + // should not lint + Self { + inner: Default::default(), + } + } +} + +#[derive(Default)] +struct GenericStruct { + t: T, +} + +impl GenericStruct { + fn new() -> Self { + // should not lint + Self { t: T::default() } + } + + fn new2() -> Self { + // should not lint + Self { t: Default::default() } + } +} + +struct FakeDefault; +impl FakeDefault { + fn default() -> Self { + Self + } +} + +impl Default for FakeDefault { + fn default() -> Self { + Self + } +} + +#[derive(Default)] +struct EmptyStruct {} + +#[derive(Default)] +#[non_exhaustive] +struct NonExhaustiveStruct; + +<<<<<<< HEAD +mod issue_10755 { + struct Sqlite {} + + trait HasArguments<'q> { + type Arguments; + } + + impl<'q> HasArguments<'q> for Sqlite { + type Arguments = std::marker::PhantomData<&'q ()>; + } + + type SqliteArguments<'q> = >::Arguments; + + fn foo() { + // should not lint + // type alias cannot be used as a constructor + let _ = ::Arguments::default(); + + let _ = SqliteArguments::default(); + } +} + +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +fn main() { + // should lint + let _ = PhantomData::; + let _: PhantomData = PhantomData; +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + let _: PhantomData = std::marker::PhantomData; +======= +<<<<<<< HEAD +>>>>>>> 160371550 (add `rustfix` annotation) +======= + let _: PhantomData = std::marker::PhantomData; +>>>>>>> 68eb864c9 (Ignore expressions from macros in default_constructed_unit_structs) +======= +>>>>>>> 7e9abb311 (Merge commit '371120bdbf58a331db5dcfb2d9cddc040f486de8' into clippyup) +======= + let _: PhantomData = std::marker::PhantomData; +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= + let _: PhantomData = std::marker::PhantomData; +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + let _ = UnitStruct; + + // should not lint + let _ = TupleStruct::default(); + let _ = NormalStruct::default(); + let _ = NonExhaustiveStruct::default(); + let _ = SomeEnum::default(); + let _ = NonDefaultStruct::default(); + let _ = EmptyStruct::default(); + let _ = FakeDefault::default(); + let _ = ::default(); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +<<<<<<< HEAD +>>>>>>> 68eb864c9 (Ignore expressions from macros in default_constructed_unit_structs) +======= +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + + macro_rules! in_macro { + ($i:ident) => {{ + let _ = UnitStruct::default(); + let _ = $i::default(); + }}; + } + + in_macro!(UnitStruct); + + macro_rules! struct_from_macro { + () => { + UnitStruct + }; + } + + let _ = ::default(); +<<<<<<< HEAD +<<<<<<< HEAD +======= +<<<<<<< HEAD +>>>>>>> 160371550 (add `rustfix` annotation) +======= +>>>>>>> 68eb864c9 (Ignore expressions from macros in default_constructed_unit_structs) +======= +>>>>>>> 7e9abb311 (Merge commit '371120bdbf58a331db5dcfb2d9cddc040f486de8' into clippyup) +======= +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) +} diff --git a/tests/ui/default_constructed_unit_structs.rs b/tests/ui/default_constructed_unit_structs.rs new file mode 100644 index 000000000000..dd90195a1cdb --- /dev/null +++ b/tests/ui/default_constructed_unit_structs.rs @@ -0,0 +1,254 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix + +======= +>>>>>>> 4e0490363 (rename to plural form) +======= +//@run-rustfix + +>>>>>>> 160371550 (add `rustfix` annotation) +#![allow(unused)] +#![warn(clippy::default_constructed_unit_structs)] +use std::marker::PhantomData; + +#[derive(Default)] +struct UnitStruct; + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 870100986 (add more test cases) +impl UnitStruct { + fn new() -> Self { + //should lint + Self::default() + } +} + +#[derive(Default)] +struct TupleStruct(usize); + +impl TupleStruct { + fn new() -> Self { + // should not lint + Self(Default::default()) + } +} + +<<<<<<< HEAD +======= +#[derive(Default)] +struct TupleStruct(usize); + +>>>>>>> 4e0490363 (rename to plural form) +======= +>>>>>>> 870100986 (add more test cases) +// no lint for derived impl +#[derive(Default)] +struct NormalStruct { + inner: PhantomData, +} + +struct NonDefaultStruct; + +impl NonDefaultStruct { + fn default() -> Self { + Self + } +} + +#[derive(Default)] +enum SomeEnum { + #[default] + Unit, + Tuple(UnitStruct), + Struct { + inner: usize, + }, +} + +impl NormalStruct { + fn new() -> Self { + // should lint + Self { + inner: PhantomData::default(), + } + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 870100986 (add more test cases) + + fn new2() -> Self { + // should not lint + Self { + inner: Default::default(), + } + } +<<<<<<< HEAD +======= +>>>>>>> 4e0490363 (rename to plural form) +======= +>>>>>>> 870100986 (add more test cases) +} + +#[derive(Default)] +struct GenericStruct { + t: T, +} + +impl GenericStruct { + fn new() -> Self { + // should not lint + Self { t: T::default() } + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 870100986 (add more test cases) + + fn new2() -> Self { + // should not lint + Self { t: Default::default() } + } +} + +struct FakeDefault; +impl FakeDefault { + fn default() -> Self { + Self + } +} + +impl Default for FakeDefault { + fn default() -> Self { + Self + } +} + +#[derive(Default)] +struct EmptyStruct {} + +<<<<<<< HEAD +======= +} + +>>>>>>> 4e0490363 (rename to plural form) +======= +>>>>>>> 870100986 (add more test cases) +#[derive(Default)] +#[non_exhaustive] +struct NonExhaustiveStruct; + +<<<<<<< HEAD +mod issue_10755 { + struct Sqlite {} + + trait HasArguments<'q> { + type Arguments; + } + + impl<'q> HasArguments<'q> for Sqlite { + type Arguments = std::marker::PhantomData<&'q ()>; + } + + type SqliteArguments<'q> = >::Arguments; + + fn foo() { + // should not lint + // type alias cannot be used as a constructor + let _ = ::Arguments::default(); + + let _ = SqliteArguments::default(); + } +} + +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +fn main() { + // should lint + let _ = PhantomData::::default(); + let _: PhantomData = PhantomData::default(); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + let _: PhantomData = std::marker::PhantomData::default(); +======= +<<<<<<< HEAD +>>>>>>> 4e0490363 (rename to plural form) +======= + let _: PhantomData = std::marker::PhantomData::default(); +>>>>>>> 68eb864c9 (Ignore expressions from macros in default_constructed_unit_structs) +======= +>>>>>>> 7e9abb311 (Merge commit '371120bdbf58a331db5dcfb2d9cddc040f486de8' into clippyup) +======= + let _: PhantomData = std::marker::PhantomData::default(); +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= + let _: PhantomData = std::marker::PhantomData::default(); +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + let _ = UnitStruct::default(); + + // should not lint + let _ = TupleStruct::default(); + let _ = NormalStruct::default(); + let _ = NonExhaustiveStruct::default(); + let _ = SomeEnum::default(); + let _ = NonDefaultStruct::default(); +<<<<<<< HEAD +<<<<<<< HEAD + let _ = EmptyStruct::default(); + let _ = FakeDefault::default(); + let _ = ::default(); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) + + macro_rules! in_macro { + ($i:ident) => {{ + let _ = UnitStruct::default(); + let _ = $i::default(); + }}; + } + + in_macro!(UnitStruct); + + macro_rules! struct_from_macro { + () => { + UnitStruct + }; + } + + let _ = ::default(); +<<<<<<< HEAD +<<<<<<< HEAD +======= +<<<<<<< HEAD +>>>>>>> 4e0490363 (rename to plural form) +======= + let _ = EmptyStruct::default(); + let _ = FakeDefault::default(); + let _ = ::default(); +>>>>>>> 870100986 (add more test cases) +======= +>>>>>>> 68eb864c9 (Ignore expressions from macros in default_constructed_unit_structs) +======= +>>>>>>> 7e9abb311 (Merge commit '371120bdbf58a331db5dcfb2d9cddc040f486de8' into clippyup) +======= +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) +} diff --git a/tests/ui/default_constructed_unit_structs.stderr b/tests/ui/default_constructed_unit_structs.stderr new file mode 100644 index 000000000000..fff891e275df --- /dev/null +++ b/tests/ui/default_constructed_unit_structs.stderr @@ -0,0 +1,197 @@ +error: use of `default` to create a unit struct +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/default_constructed_unit_structs.rs:13:13 + | +LL | Self::default() + | ^^^^^^^^^^^ help: remove this call to `default` +======= + --> $DIR/default_constructed_unit_structs.rs:39:31 + | +LL | inner: PhantomData::default(), + | ^^^^^^^^^^^ help: remove this call to `default` +>>>>>>> 4e0490363 (rename to plural form) +======= + --> $DIR/default_constructed_unit_structs.rs:11:13 +======= + --> $DIR/default_constructed_unit_structs.rs:13:13 +>>>>>>> 160371550 (add `rustfix` annotation) + | +LL | Self::default() + | ^^^^^^^^^^^ help: remove this call to `default` +>>>>>>> 870100986 (add more test cases) + | + = note: `-D clippy::default-constructed-unit-structs` implied by `-D warnings` + +error: use of `default` to create a unit struct +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/default_constructed_unit_structs.rs:55:31 +======= + --> $DIR/default_constructed_unit_structs.rs:53:31 +>>>>>>> 870100986 (add more test cases) +======= + --> $DIR/default_constructed_unit_structs.rs:55:31 +>>>>>>> 160371550 (add `rustfix` annotation) + | +LL | inner: PhantomData::default(), + | ^^^^^^^^^^^ help: remove this call to `default` + +error: use of `default` to create a unit struct +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/default_constructed_unit_structs.rs:106:33 +======= + --> $DIR/default_constructed_unit_structs.rs:62:33 +>>>>>>> 4e0490363 (rename to plural form) +======= + --> $DIR/default_constructed_unit_structs.rs:104:33 +>>>>>>> 870100986 (add more test cases) +======= + --> $DIR/default_constructed_unit_structs.rs:106:33 +>>>>>>> 160371550 (add `rustfix` annotation) +======= + --> $DIR/default_constructed_unit_structs.rs:128:33 +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= + --> $DIR/default_constructed_unit_structs.rs:128:33 +======= + --> $DIR/default_constructed_unit_structs.rs:106:33 +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + | +LL | let _ = PhantomData::::default(); + | ^^^^^^^^^^^ help: remove this call to `default` + +error: use of `default` to create a unit struct +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/default_constructed_unit_structs.rs:107:42 +======= + --> $DIR/default_constructed_unit_structs.rs:63:42 +>>>>>>> 4e0490363 (rename to plural form) +======= + --> $DIR/default_constructed_unit_structs.rs:105:42 +>>>>>>> 870100986 (add more test cases) +======= + --> $DIR/default_constructed_unit_structs.rs:107:42 +>>>>>>> 160371550 (add `rustfix` annotation) +======= + --> $DIR/default_constructed_unit_structs.rs:129:42 +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= + --> $DIR/default_constructed_unit_structs.rs:129:42 +======= + --> $DIR/default_constructed_unit_structs.rs:107:42 +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + | +LL | let _: PhantomData = PhantomData::default(); + | ^^^^^^^^^^^ help: remove this call to `default` + +error: use of `default` to create a unit struct +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +<<<<<<< HEAD +>>>>>>> 68eb864c9 (Ignore expressions from macros in default_constructed_unit_structs) +======= +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) + --> $DIR/default_constructed_unit_structs.rs:108:55 +======= + --> $DIR/default_constructed_unit_structs.rs:130:55 +>>>>>>> e6dc0efc0 (Merge commit '30448e8cf98d4754350db0c959644564f317bc0f' into clippyup) +======= + --> $DIR/default_constructed_unit_structs.rs:130:55 +>>>>>>> 8c82486ea ([`default_constructed_unit_structs`]: do not lint type aliases) +======= + --> $DIR/default_constructed_unit_structs.rs:108:55 +>>>>>>> e4f5d83fa (Fixed formatting.) + | +LL | let _: PhantomData = std::marker::PhantomData::default(); + | ^^^^^^^^^^^ help: remove this call to `default` + +error: use of `default` to create a unit struct +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/default_constructed_unit_structs.rs:109:23 +<<<<<<< HEAD +======= +<<<<<<< HEAD + --> $DIR/default_constructed_unit_structs.rs:64:23 +>>>>>>> 4e0490363 (rename to plural form) +======= + --> $DIR/default_constructed_unit_structs.rs:106:23 +>>>>>>> 870100986 (add more test cases) +======= + --> $DIR/default_constructed_unit_structs.rs:108:23 +>>>>>>> 160371550 (add `rustfix` annotation) +======= +>>>>>>> 68eb864c9 (Ignore expressions from macros in default_constructed_unit_structs) +======= + --> $DIR/default_constructed_unit_structs.rs:108:23 +>>>>>>> 7e9abb311 (Merge commit '371120bdbf58a331db5dcfb2d9cddc040f486de8' into clippyup) +======= +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +======= + --> $DIR/default_constructed_unit_structs.rs:131:23 +>>>>>>> e6dc0efc0 (Merge commit '30448e8cf98d4754350db0c959644564f317bc0f' into clippyup) +======= + --> $DIR/default_constructed_unit_structs.rs:131:23 +>>>>>>> 8c82486ea ([`default_constructed_unit_structs`]: do not lint type aliases) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= + --> $DIR/default_constructed_unit_structs.rs:109:23 +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + | +LL | let _ = UnitStruct::default(); + | ^^^^^^^^^^^ help: remove this call to `default` + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 6 previous errors +======= +error: aborting due to 4 previous errors +>>>>>>> 4e0490363 (rename to plural form) +======= +error: aborting due to 5 previous errors +>>>>>>> 870100986 (add more test cases) +======= +error: aborting due to 6 previous errors +>>>>>>> 68eb864c9 (Ignore expressions from macros in default_constructed_unit_structs) +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +error: aborting due to 6 previous errors +======= +error: aborting due to 5 previous errors +>>>>>>> 7e9abb311 (Merge commit '371120bdbf58a331db5dcfb2d9cddc040f486de8' into clippyup) +======= +error: aborting due to 6 previous errors +>>>>>>> b76b0aeb6 (Merge commit '435a8ad86c7a33bd7ffb91c59039943408d3b6aa' into clippyup) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +error: aborting due to 6 previous errors +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + diff --git a/tests/ui/default_instead_of_iter_empty.fixed b/tests/ui/default_instead_of_iter_empty.fixed index f1abfdcd6ce6..f44d34576f68 100644 --- a/tests/ui/default_instead_of_iter_empty.fixed +++ b/tests/ui/default_instead_of_iter_empty.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::default_instead_of_iter_empty)] #![allow(dead_code)] use std::collections::HashMap; diff --git a/tests/ui/default_instead_of_iter_empty.rs b/tests/ui/default_instead_of_iter_empty.rs index 2630519c46da..1c649df253cc 100644 --- a/tests/ui/default_instead_of_iter_empty.rs +++ b/tests/ui/default_instead_of_iter_empty.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::default_instead_of_iter_empty)] #![allow(dead_code)] use std::collections::HashMap; diff --git a/tests/ui/default_numeric_fallback_f64.fixed b/tests/ui/default_numeric_fallback_f64.fixed index 42c15d6a70b8..b5fa86fe858d 100644 --- a/tests/ui/default_numeric_fallback_f64.fixed +++ b/tests/ui/default_numeric_fallback_f64.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::default_numeric_fallback)] #![allow( diff --git a/tests/ui/default_numeric_fallback_f64.rs b/tests/ui/default_numeric_fallback_f64.rs index 7da7ea254e98..31273ed440fb 100644 --- a/tests/ui/default_numeric_fallback_f64.rs +++ b/tests/ui/default_numeric_fallback_f64.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::default_numeric_fallback)] #![allow( diff --git a/tests/ui/default_numeric_fallback_i32.fixed b/tests/ui/default_numeric_fallback_i32.fixed index b7485b73dcdd..22c1f93a61f1 100644 --- a/tests/ui/default_numeric_fallback_i32.fixed +++ b/tests/ui/default_numeric_fallback_i32.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] diff --git a/tests/ui/default_numeric_fallback_i32.rs b/tests/ui/default_numeric_fallback_i32.rs index 7307d31354eb..7764c46583e9 100644 --- a/tests/ui/default_numeric_fallback_i32.rs +++ b/tests/ui/default_numeric_fallback_i32.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] diff --git a/tests/ui/default_trait_access.fixed b/tests/ui/default_trait_access.fixed index 7842ef3ec40c..242cec0c1d99 100644 --- a/tests/ui/default_trait_access.fixed +++ b/tests/ui/default_trait_access.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![deny(clippy::default_trait_access)] #![allow(dead_code, unused_imports)] #![allow(clippy::uninlined_format_args)] @@ -7,9 +11,8 @@ extern crate proc_macros; use proc_macros::with_span; -use std::default; use std::default::Default as D2; -use std::string; +use std::{default, string}; fn main() { let s1: String = String::default(); diff --git a/tests/ui/default_trait_access.rs b/tests/ui/default_trait_access.rs index cbb3e59c970e..ba8dd40ab13a 100644 --- a/tests/ui/default_trait_access.rs +++ b/tests/ui/default_trait_access.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![deny(clippy::default_trait_access)] #![allow(dead_code, unused_imports)] #![allow(clippy::uninlined_format_args)] @@ -7,9 +11,8 @@ extern crate proc_macros; use proc_macros::with_span; -use std::default; use std::default::Default as D2; -use std::string; +use std::{default, string}; fn main() { let s1: String = Default::default(); diff --git a/tests/ui/default_trait_access.stderr b/tests/ui/default_trait_access.stderr index e4f73c08d190..103fccf6a1d3 100644 --- a/tests/ui/default_trait_access.stderr +++ b/tests/ui/default_trait_access.stderr @@ -1,5 +1,5 @@ error: calling `String::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:15:22 + --> $DIR/default_trait_access.rs:14:22 | LL | let s1: String = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `String::default()` @@ -11,43 +11,43 @@ LL | #![deny(clippy::default_trait_access)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: calling `String::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:19:22 + --> $DIR/default_trait_access.rs:18:22 | LL | let s3: String = D2::default(); | ^^^^^^^^^^^^^ help: try: `String::default()` error: calling `String::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:21:22 + --> $DIR/default_trait_access.rs:20:22 | LL | let s4: String = std::default::Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `String::default()` error: calling `String::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:25:22 + --> $DIR/default_trait_access.rs:24:22 | LL | let s6: String = default::Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `String::default()` error: calling `GenericDerivedDefault::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:35:46 + --> $DIR/default_trait_access.rs:34:46 | LL | let s11: GenericDerivedDefault = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `GenericDerivedDefault::default()` error: calling `TupleDerivedDefault::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:41:36 + --> $DIR/default_trait_access.rs:40:36 | LL | let s14: TupleDerivedDefault = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `TupleDerivedDefault::default()` error: calling `ArrayDerivedDefault::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:43:36 + --> $DIR/default_trait_access.rs:42:36 | LL | let s15: ArrayDerivedDefault = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `ArrayDerivedDefault::default()` error: calling `TupleStructDerivedDefault::default()` is more clear than this expression - --> $DIR/default_trait_access.rs:47:42 + --> $DIR/default_trait_access.rs:46:42 | LL | let s17: TupleStructDerivedDefault = Default::default(); | ^^^^^^^^^^^^^^^^^^ help: try: `TupleStructDerivedDefault::default()` diff --git a/tests/ui/deref_addrof.fixed b/tests/ui/deref_addrof.fixed index ca5c03304c7f..9ce9733e4cdf 100644 --- a/tests/ui/deref_addrof.fixed +++ b/tests/ui/deref_addrof.fixed @@ -1,7 +1,11 @@ -// run-rustfix -// aux-build:proc_macros.rs - -#![allow(clippy::return_self_not_must_use)] +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) + +#![allow(clippy::return_self_not_must_use, clippy::useless_vec)] #![warn(clippy::deref_addrof)] extern crate proc_macros; diff --git a/tests/ui/deref_addrof.rs b/tests/ui/deref_addrof.rs index 3db5fafe9449..043975810d70 100644 --- a/tests/ui/deref_addrof.rs +++ b/tests/ui/deref_addrof.rs @@ -1,7 +1,11 @@ -// run-rustfix -// aux-build:proc_macros.rs - -#![allow(clippy::return_self_not_must_use)] +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) + +#![allow(clippy::return_self_not_must_use, clippy::useless_vec)] #![warn(clippy::deref_addrof)] extern crate proc_macros; diff --git a/tests/ui/deref_addrof.stderr b/tests/ui/deref_addrof.stderr index e0287522fc56..9dd1e246b3e4 100644 --- a/tests/ui/deref_addrof.stderr +++ b/tests/ui/deref_addrof.stderr @@ -2,7 +2,7 @@ error: immediately dereferencing a reference --> $DIR/deref_addrof.rs:24:13 | LL | let b = *&a; - | ^^^ help: try this: `a` + | ^^^ help: try: `a` | = note: `-D clippy::deref-addrof` implied by `-D warnings` @@ -10,49 +10,49 @@ error: immediately dereferencing a reference --> $DIR/deref_addrof.rs:26:13 | LL | let b = *&get_number(); - | ^^^^^^^^^^^^^^ help: try this: `get_number()` + | ^^^^^^^^^^^^^^ help: try: `get_number()` error: immediately dereferencing a reference --> $DIR/deref_addrof.rs:31:13 | LL | let b = *&bytes[1..2][0]; - | ^^^^^^^^^^^^^^^^ help: try this: `bytes[1..2][0]` + | ^^^^^^^^^^^^^^^^ help: try: `bytes[1..2][0]` error: immediately dereferencing a reference --> $DIR/deref_addrof.rs:35:13 | LL | let b = *&(a); - | ^^^^^ help: try this: `(a)` + | ^^^^^ help: try: `(a)` error: immediately dereferencing a reference --> $DIR/deref_addrof.rs:37:13 | LL | let b = *(&a); - | ^^^^^ help: try this: `a` + | ^^^^^ help: try: `a` error: immediately dereferencing a reference --> $DIR/deref_addrof.rs:40:13 | LL | let b = *((&a)); - | ^^^^^^^ help: try this: `a` + | ^^^^^^^ help: try: `a` error: immediately dereferencing a reference --> $DIR/deref_addrof.rs:42:13 | LL | let b = *&&a; - | ^^^^ help: try this: `&a` + | ^^^^ help: try: `&a` error: immediately dereferencing a reference --> $DIR/deref_addrof.rs:44:14 | LL | let b = **&aref; - | ^^^^^^ help: try this: `aref` + | ^^^^^^ help: try: `aref` error: immediately dereferencing a reference --> $DIR/deref_addrof.rs:54:17 | LL | inline!(*& $(@expr self)) - | ^^^^^^^^^^^^^^^^ help: try this: `$(@expr self)` + | ^^^^^^^^^^^^^^^^ help: try: `$(@expr self)` | = note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -60,7 +60,7 @@ error: immediately dereferencing a reference --> $DIR/deref_addrof.rs:58:17 | LL | inline!(*&mut $(@expr self)) - | ^^^^^^^^^^^^^^^^^^^ help: try this: `$(@expr self)` + | ^^^^^^^^^^^^^^^^^^^ help: try: `$(@expr self)` | = note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/deref_addrof_double_trigger.stderr b/tests/ui/deref_addrof_double_trigger.stderr index 2c55a4ed6acd..6fa5069b6b4b 100644 --- a/tests/ui/deref_addrof_double_trigger.stderr +++ b/tests/ui/deref_addrof_double_trigger.stderr @@ -2,7 +2,7 @@ error: immediately dereferencing a reference --> $DIR/deref_addrof_double_trigger.rs:10:14 | LL | let b = **&&a; - | ^^^^ help: try this: `&a` + | ^^^^ help: try: `&a` | = note: `-D clippy::deref-addrof` implied by `-D warnings` @@ -10,13 +10,13 @@ error: immediately dereferencing a reference --> $DIR/deref_addrof_double_trigger.rs:14:17 | LL | let y = *&mut x; - | ^^^^^^^ help: try this: `x` + | ^^^^^^^ help: try: `x` error: immediately dereferencing a reference --> $DIR/deref_addrof_double_trigger.rs:21:18 | LL | let y = **&mut &mut x; - | ^^^^^^^^^^^^ help: try this: `&mut x` + | ^^^^^^^^^^^^ help: try: `&mut x` error: aborting due to 3 previous errors diff --git a/tests/ui/deref_addrof_macro.rs b/tests/ui/deref_addrof_macro.rs index 57c0be3f51e1..e03d2634d36c 100644 --- a/tests/ui/deref_addrof_macro.rs +++ b/tests/ui/deref_addrof_macro.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::deref_addrof)] diff --git a/tests/ui/deref_by_slicing.fixed b/tests/ui/deref_by_slicing.fixed index 257393e56ff0..f91a425c65da 100644 --- a/tests/ui/deref_by_slicing.fixed +++ b/tests/ui/deref_by_slicing.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::deref_by_slicing)] #![allow(clippy::borrow_deref_ref)] diff --git a/tests/ui/deref_by_slicing.rs b/tests/ui/deref_by_slicing.rs index e288046f927f..1bfdd0a981ba 100644 --- a/tests/ui/deref_by_slicing.rs +++ b/tests/ui/deref_by_slicing.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::deref_by_slicing)] #![allow(clippy::borrow_deref_ref)] diff --git a/tests/ui/derivable_impls.fixed b/tests/ui/derivable_impls.fixed index 89ec33a0d8f7..a10f3d010707 100644 --- a/tests/ui/derivable_impls.fixed +++ b/tests/ui/derivable_impls.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] @@ -268,4 +268,25 @@ impl Default for OtherGenericType { } } +mod issue10158 { + pub trait T {} + + #[derive(Default)] + pub struct S {} + impl T for S {} + + pub struct Outer { + pub inner: Box, + } + + impl Default for Outer { + fn default() -> Self { + Outer { + // Box::::default() adjusts to Box + inner: Box::::default(), + } + } + } +} + fn main() {} diff --git a/tests/ui/derivable_impls.rs b/tests/ui/derivable_impls.rs index def6e41162f1..18cef1c5be89 100644 --- a/tests/ui/derivable_impls.rs +++ b/tests/ui/derivable_impls.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] @@ -304,4 +304,25 @@ impl Default for OtherGenericType { } } +mod issue10158 { + pub trait T {} + + #[derive(Default)] + pub struct S {} + impl T for S {} + + pub struct Outer { + pub inner: Box, + } + + impl Default for Outer { + fn default() -> Self { + Outer { + // Box::::default() adjusts to Box + inner: Box::::default(), + } + } + } +} + fn main() {} diff --git a/tests/ui/derivable_impls.stderr b/tests/ui/derivable_impls.stderr index 81963c3be5b5..8089f5ea0fcb 100644 --- a/tests/ui/derivable_impls.stderr +++ b/tests/ui/derivable_impls.stderr @@ -14,7 +14,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct FooDefault<'a> { | error: this `impl` can be derived @@ -30,7 +31,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct TupleDefault(bool, i32, u64); | error: this `impl` can be derived @@ -46,7 +48,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct StrDefault<'a>(&'a str); | error: this `impl` can be derived @@ -62,7 +65,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct Y(u32); | error: this `impl` can be derived @@ -78,7 +82,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct WithoutSelfCurly { | error: this `impl` can be derived @@ -94,7 +99,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct WithoutSelfParan(bool); | error: this `impl` can be derived @@ -110,7 +116,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | pub struct RepeatDefault1 { | error: this `impl` can be derived @@ -126,7 +133,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it... | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | pub enum SimpleEnum { | help: ...and mark the default variant | diff --git a/tests/ui/derive.rs b/tests/ui/derive.rs index 843e1df8bc6b..a31992bf9e86 100644 --- a/tests/ui/derive.rs +++ b/tests/ui/derive.rs @@ -1,4 +1,20 @@ -#![allow(dead_code)] +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::incorrect_clone_impl_on_copy_type, dead_code)] +======= +#![allow(clippy::needless_clone_impl, dead_code)] +>>>>>>> 67d5e6ec3 (add lint [`needless_clone_impl`]) +======= +#![allow(clippy::incorrect_clone_impl_on_copy_type, dead_code)] +>>>>>>> 10cc1684c (rename lint and disallow `clone_from`) +======= +#![allow( + clippy::incorrect_clone_impl_on_copy_type, + clippy::incorrect_partial_ord_impl_on_ord_type, + dead_code +)] +>>>>>>> 844afbfeb (use `other` instead of `self`) #![warn(clippy::expl_impl_clone_on_copy)] #[derive(Copy)] diff --git a/tests/ui/derive.stderr b/tests/ui/derive.stderr index d37f7fa73319..f7948e044b7e 100644 --- a/tests/ui/derive.stderr +++ b/tests/ui/derive.stderr @@ -1,5 +1,5 @@ error: you are implementing `Clone` explicitly on a `Copy` type - --> $DIR/derive.rs:7:1 + --> $DIR/derive.rs:11:1 | LL | / impl Clone for Qux { LL | | fn clone(&self) -> Self { @@ -9,7 +9,7 @@ LL | | } | |_^ | note: consider deriving `Clone` or removing `Copy` - --> $DIR/derive.rs:7:1 + --> $DIR/derive.rs:11:1 | LL | / impl Clone for Qux { LL | | fn clone(&self) -> Self { @@ -20,7 +20,7 @@ LL | | } = note: `-D clippy::expl-impl-clone-on-copy` implied by `-D warnings` error: you are implementing `Clone` explicitly on a `Copy` type - --> $DIR/derive.rs:31:1 + --> $DIR/derive.rs:35:1 | LL | / impl<'a> Clone for Lt<'a> { LL | | fn clone(&self) -> Self { @@ -30,7 +30,7 @@ LL | | } | |_^ | note: consider deriving `Clone` or removing `Copy` - --> $DIR/derive.rs:31:1 + --> $DIR/derive.rs:35:1 | LL | / impl<'a> Clone for Lt<'a> { LL | | fn clone(&self) -> Self { @@ -40,7 +40,7 @@ LL | | } | |_^ error: you are implementing `Clone` explicitly on a `Copy` type - --> $DIR/derive.rs:42:1 + --> $DIR/derive.rs:46:1 | LL | / impl Clone for BigArray { LL | | fn clone(&self) -> Self { @@ -50,7 +50,7 @@ LL | | } | |_^ | note: consider deriving `Clone` or removing `Copy` - --> $DIR/derive.rs:42:1 + --> $DIR/derive.rs:46:1 | LL | / impl Clone for BigArray { LL | | fn clone(&self) -> Self { @@ -60,7 +60,7 @@ LL | | } | |_^ error: you are implementing `Clone` explicitly on a `Copy` type - --> $DIR/derive.rs:53:1 + --> $DIR/derive.rs:57:1 | LL | / impl Clone for FnPtr { LL | | fn clone(&self) -> Self { @@ -70,7 +70,7 @@ LL | | } | |_^ | note: consider deriving `Clone` or removing `Copy` - --> $DIR/derive.rs:53:1 + --> $DIR/derive.rs:57:1 | LL | / impl Clone for FnPtr { LL | | fn clone(&self) -> Self { @@ -80,7 +80,7 @@ LL | | } | |_^ error: you are implementing `Clone` explicitly on a `Copy` type - --> $DIR/derive.rs:73:1 + --> $DIR/derive.rs:77:1 | LL | / impl Clone for Generic2 { LL | | fn clone(&self) -> Self { @@ -90,7 +90,7 @@ LL | | } | |_^ | note: consider deriving `Clone` or removing `Copy` - --> $DIR/derive.rs:73:1 + --> $DIR/derive.rs:77:1 | LL | / impl Clone for Generic2 { LL | | fn clone(&self) -> Self { diff --git a/tests/ui/derive_ord_xor_partial_ord.rs b/tests/ui/derive_ord_xor_partial_ord.rs index 6f12d36d777d..1fb3d51c46dc 100644 --- a/tests/ui/derive_ord_xor_partial_ord.rs +++ b/tests/ui/derive_ord_xor_partial_ord.rs @@ -1,5 +1,6 @@ #![warn(clippy::derive_ord_xor_partial_ord)] #![allow(clippy::unnecessary_wraps)] +#![allow(clippy::incorrect_partial_ord_impl_on_ord_type)] use std::cmp::Ordering; diff --git a/tests/ui/derive_ord_xor_partial_ord.stderr b/tests/ui/derive_ord_xor_partial_ord.stderr index 58efbb8541f6..bd1488348140 100644 --- a/tests/ui/derive_ord_xor_partial_ord.stderr +++ b/tests/ui/derive_ord_xor_partial_ord.stderr @@ -1,11 +1,11 @@ error: you are deriving `Ord` but have implemented `PartialOrd` explicitly - --> $DIR/derive_ord_xor_partial_ord.rs:21:10 + --> $DIR/derive_ord_xor_partial_ord.rs:22:10 | LL | #[derive(Ord, PartialEq, Eq)] | ^^^ | note: `PartialOrd` implemented here - --> $DIR/derive_ord_xor_partial_ord.rs:24:1 + --> $DIR/derive_ord_xor_partial_ord.rs:25:1 | LL | impl PartialOrd for DeriveOrd { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,20 +13,20 @@ LL | impl PartialOrd for DeriveOrd { = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `Ord` but have implemented `PartialOrd` explicitly - --> $DIR/derive_ord_xor_partial_ord.rs:30:10 + --> $DIR/derive_ord_xor_partial_ord.rs:31:10 | LL | #[derive(Ord, PartialEq, Eq)] | ^^^ | note: `PartialOrd` implemented here - --> $DIR/derive_ord_xor_partial_ord.rs:33:1 + --> $DIR/derive_ord_xor_partial_ord.rs:34:1 | LL | impl PartialOrd for DeriveOrdWithExplicitTypeVariable { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are implementing `Ord` explicitly but have derived `PartialOrd` - --> $DIR/derive_ord_xor_partial_ord.rs:42:1 + --> $DIR/derive_ord_xor_partial_ord.rs:43:1 | LL | / impl std::cmp::Ord for DerivePartialOrd { LL | | fn cmp(&self, other: &Self) -> Ordering { @@ -36,14 +36,14 @@ LL | | } | |_^ | note: `PartialOrd` implemented here - --> $DIR/derive_ord_xor_partial_ord.rs:39:10 + --> $DIR/derive_ord_xor_partial_ord.rs:40:10 | LL | #[derive(PartialOrd, PartialEq, Eq)] | ^^^^^^^^^^ = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are implementing `Ord` explicitly but have derived `PartialOrd` - --> $DIR/derive_ord_xor_partial_ord.rs:62:5 + --> $DIR/derive_ord_xor_partial_ord.rs:63:5 | LL | / impl Ord for DerivePartialOrdInUseOrd { LL | | fn cmp(&self, other: &Self) -> Ordering { @@ -53,7 +53,7 @@ LL | | } | |_____^ | note: `PartialOrd` implemented here - --> $DIR/derive_ord_xor_partial_ord.rs:59:14 + --> $DIR/derive_ord_xor_partial_ord.rs:60:14 | LL | #[derive(PartialOrd, PartialEq, Eq)] | ^^^^^^^^^^ diff --git a/tests/ui/derive_partial_eq_without_eq.fixed b/tests/ui/derive_partial_eq_without_eq.fixed index bbbe467590f9..a1f29430c30f 100644 --- a/tests/ui/derive_partial_eq_without_eq.fixed +++ b/tests/ui/derive_partial_eq_without_eq.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::derive_partial_eq_without_eq)] diff --git a/tests/ui/derive_partial_eq_without_eq.rs b/tests/ui/derive_partial_eq_without_eq.rs index 88d6fbd1af7e..ff4d888559b7 100644 --- a/tests/ui/derive_partial_eq_without_eq.rs +++ b/tests/ui/derive_partial_eq_without_eq.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::derive_partial_eq_without_eq)] diff --git a/tests/ui/disallowed_names.rs b/tests/ui/disallowed_names.rs index e937c49f3897..5889f04439ff 100644 --- a/tests/ui/disallowed_names.rs +++ b/tests/ui/disallowed_names.rs @@ -1,5 +1,6 @@ #![allow( dead_code, + clippy::needless_if, clippy::similar_names, clippy::single_match, clippy::toplevel_ref_arg, diff --git a/tests/ui/disallowed_names.stderr b/tests/ui/disallowed_names.stderr index 78cb55096ff0..9ab68b641f13 100644 --- a/tests/ui/disallowed_names.stderr +++ b/tests/ui/disallowed_names.stderr @@ -1,5 +1,5 @@ error: use of a disallowed/placeholder name `foo` - --> $DIR/disallowed_names.rs:11:9 + --> $DIR/disallowed_names.rs:12:9 | LL | fn test(foo: ()) {} | ^^^ @@ -7,79 +7,79 @@ LL | fn test(foo: ()) {} = note: `-D clippy::disallowed-names` implied by `-D warnings` error: use of a disallowed/placeholder name `foo` - --> $DIR/disallowed_names.rs:14:9 + --> $DIR/disallowed_names.rs:15:9 | LL | let foo = 42; | ^^^ error: use of a disallowed/placeholder name `baz` - --> $DIR/disallowed_names.rs:15:9 + --> $DIR/disallowed_names.rs:16:9 | LL | let baz = 42; | ^^^ error: use of a disallowed/placeholder name `quux` - --> $DIR/disallowed_names.rs:16:9 + --> $DIR/disallowed_names.rs:17:9 | LL | let quux = 42; | ^^^^ error: use of a disallowed/placeholder name `foo` - --> $DIR/disallowed_names.rs:27:10 + --> $DIR/disallowed_names.rs:28:10 | LL | (foo, Some(baz), quux @ Some(_)) => (), | ^^^ error: use of a disallowed/placeholder name `baz` - --> $DIR/disallowed_names.rs:27:20 + --> $DIR/disallowed_names.rs:28:20 | LL | (foo, Some(baz), quux @ Some(_)) => (), | ^^^ error: use of a disallowed/placeholder name `quux` - --> $DIR/disallowed_names.rs:27:26 + --> $DIR/disallowed_names.rs:28:26 | LL | (foo, Some(baz), quux @ Some(_)) => (), | ^^^^ error: use of a disallowed/placeholder name `foo` - --> $DIR/disallowed_names.rs:32:19 + --> $DIR/disallowed_names.rs:33:19 | LL | fn issue_1647(mut foo: u8) { | ^^^ error: use of a disallowed/placeholder name `baz` - --> $DIR/disallowed_names.rs:33:13 + --> $DIR/disallowed_names.rs:34:13 | LL | let mut baz = 0; | ^^^ error: use of a disallowed/placeholder name `quux` - --> $DIR/disallowed_names.rs:34:21 + --> $DIR/disallowed_names.rs:35:21 | LL | if let Some(mut quux) = Some(42) {} | ^^^^ error: use of a disallowed/placeholder name `baz` - --> $DIR/disallowed_names.rs:38:13 + --> $DIR/disallowed_names.rs:39:13 | LL | let ref baz = 0; | ^^^ error: use of a disallowed/placeholder name `quux` - --> $DIR/disallowed_names.rs:39:21 + --> $DIR/disallowed_names.rs:40:21 | LL | if let Some(ref quux) = Some(42) {} | ^^^^ error: use of a disallowed/placeholder name `baz` - --> $DIR/disallowed_names.rs:43:17 + --> $DIR/disallowed_names.rs:44:17 | LL | let ref mut baz = 0; | ^^^ error: use of a disallowed/placeholder name `quux` - --> $DIR/disallowed_names.rs:44:25 + --> $DIR/disallowed_names.rs:45:25 | LL | if let Some(ref mut quux) = Some(42) {} | ^^^^ diff --git a/tests/ui/diverging_sub_expression.rs b/tests/ui/diverging_sub_expression.rs index e8f992e6dded..0e93247a446f 100644 --- a/tests/ui/diverging_sub_expression.rs +++ b/tests/ui/diverging_sub_expression.rs @@ -1,5 +1,6 @@ #![warn(clippy::diverging_sub_expression)] #![allow(clippy::match_same_arms, clippy::overly_complex_bool_expr)] +#![allow(clippy::nonminimal_bool)] #[allow(clippy::empty_loop)] fn diverge() -> ! { loop {} @@ -21,6 +22,7 @@ fn main() { } #[allow(dead_code, unused_variables)] +#[rustfmt::skip] fn foobar() { loop { let x = match 5 { @@ -35,6 +37,34 @@ fn foobar() { 99 => return, _ => true || panic!("boo"), }, + // lint blocks as well + 15 => true || { return; }, + 16 => false || { return; }, +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 0c545c7bc (also lint single expression blocks) + // ... and when it's a single expression + 17 => true || { return }, + 18 => false || { return }, + // ... but not when there's both an expression and a statement + 19 => true || { _ = 1; return }, + 20 => false || { _ = 1; return }, + // ... or multiple statements + 21 => true || { _ = 1; return; }, + 22 => false || { _ = 1; return; }, +<<<<<<< HEAD +<<<<<<< HEAD + 23 => true || { return; true }, + 24 => true || { return; true }, +======= +>>>>>>> f4b02aa37 (fix #10776) +======= +>>>>>>> 0c545c7bc (also lint single expression blocks) +======= + 23 => true || { return; true }, + 24 => true || { return; true }, +>>>>>>> 35aff1ae8 (refactor) _ => true || break, }; } diff --git a/tests/ui/diverging_sub_expression.stderr b/tests/ui/diverging_sub_expression.stderr index 9c91d935716d..0c4342e5a5da 100644 --- a/tests/ui/diverging_sub_expression.stderr +++ b/tests/ui/diverging_sub_expression.stderr @@ -1,5 +1,9 @@ +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 0c545c7bc (also lint single expression blocks) error: sub-expression diverges - --> $DIR/diverging_sub_expression.rs:19:10 + --> $DIR/diverging_sub_expression.rs:20:10 | LL | b || diverge(); | ^^^^^^^^^ @@ -7,31 +11,31 @@ LL | b || diverge(); = note: `-D clippy::diverging-sub-expression` implied by `-D warnings` error: sub-expression diverges - --> $DIR/diverging_sub_expression.rs:20:10 + --> $DIR/diverging_sub_expression.rs:21:10 | LL | b || A.foo(); | ^^^^^^^ error: sub-expression diverges - --> $DIR/diverging_sub_expression.rs:29:26 + --> $DIR/diverging_sub_expression.rs:31:26 | LL | 6 => true || return, | ^^^^^^ error: sub-expression diverges - --> $DIR/diverging_sub_expression.rs:30:26 + --> $DIR/diverging_sub_expression.rs:32:26 | LL | 7 => true || continue, | ^^^^^^^^ error: sub-expression diverges - --> $DIR/diverging_sub_expression.rs:33:26 + --> $DIR/diverging_sub_expression.rs:35:26 | LL | 3 => true || diverge(), | ^^^^^^^^^ error: sub-expression diverges - --> $DIR/diverging_sub_expression.rs:36:30 + --> $DIR/diverging_sub_expression.rs:38:30 | LL | _ => true || panic!("boo"), | ^^^^^^^^^^^^^ @@ -39,10 +43,68 @@ LL | _ => true || panic!("boo"), = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: sub-expression diverges - --> $DIR/diverging_sub_expression.rs:38:26 + --> $DIR/diverging_sub_expression.rs:41:29 + | +LL | 15 => true || { return; }, + | ^^^^^^ + +error: sub-expression diverges + --> $DIR/diverging_sub_expression.rs:42:30 + | +LL | 16 => false || { return; }, + | ^^^^^^ + +error: sub-expression diverges + --> $DIR/diverging_sub_expression.rs:44:29 + | +LL | 17 => true || { return }, + | ^^^^^^ + +error: sub-expression diverges + --> $DIR/diverging_sub_expression.rs:45:30 + | +LL | 18 => false || { return }, + | ^^^^^^ + +error: sub-expression diverges +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/diverging_sub_expression.rs:54:26 +======= + --> $DIR/diverging_sub_expression.rs:47:36 + | +LL | 19 => true || { _ = 1; return }, + | ^^^^^^ + +error: sub-expression diverges + --> $DIR/diverging_sub_expression.rs:48:37 + | +LL | 20 => false || { _ = 1; return }, + | ^^^^^^ + +error: sub-expression diverges +======= +>>>>>>> c1c134a28 (ensure there are no stmts for expr check) + --> $DIR/diverging_sub_expression.rs:52:26 +>>>>>>> 0c545c7bc (also lint single expression blocks) +======= + --> $DIR/diverging_sub_expression.rs:54:26 +>>>>>>> 35aff1ae8 (refactor) | LL | _ => true || break, | ^^^^^ -error: aborting due to 7 previous errors +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 11 previous errors + +======= +>>>>>>> f4b02aa37 (fix #10776) +======= +error: aborting due to 13 previous errors +======= +error: aborting due to 11 previous errors +>>>>>>> c1c134a28 (ensure there are no stmts for expr check) +>>>>>>> 0c545c7bc (also lint single expression blocks) diff --git a/tests/ui/doc/doc-fixable.fixed b/tests/ui/doc/doc-fixable.fixed index ecb0bf3644ee..14444df4c10e 100644 --- a/tests/ui/doc/doc-fixable.fixed +++ b/tests/ui/doc/doc-fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix //! This file tests for the `DOC_MARKDOWN` lint. #![allow(dead_code, incomplete_features)] @@ -60,6 +60,7 @@ fn test_units() { /// GitHub GitLab /// IPv4 IPv6 /// ClojureScript CoffeeScript JavaScript PureScript TypeScript +/// WebAssembly /// NaN NaNs /// OAuth GraphQL /// OCaml diff --git a/tests/ui/doc/doc-fixable.rs b/tests/ui/doc/doc-fixable.rs index 11c48dd103d6..542d33b13a4c 100644 --- a/tests/ui/doc/doc-fixable.rs +++ b/tests/ui/doc/doc-fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix //! This file tests for the `DOC_MARKDOWN` lint. #![allow(dead_code, incomplete_features)] @@ -60,6 +60,7 @@ fn test_units() { /// GitHub GitLab /// IPv4 IPv6 /// ClojureScript CoffeeScript JavaScript PureScript TypeScript +/// WebAssembly /// NaN NaNs /// OAuth GraphQL /// OCaml diff --git a/tests/ui/doc/doc-fixable.stderr b/tests/ui/doc/doc-fixable.stderr index 6c67c903c750..94ef43afc08f 100644 --- a/tests/ui/doc/doc-fixable.stderr +++ b/tests/ui/doc/doc-fixable.stderr @@ -132,7 +132,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:74:5 + --> $DIR/doc-fixable.rs:75:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -143,7 +143,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:91:5 + --> $DIR/doc-fixable.rs:92:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:99:8 + --> $DIR/doc-fixable.rs:100:8 | LL | /// ## CamelCaseThing | ^^^^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | /// ## `CamelCaseThing` | ~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:102:7 + --> $DIR/doc-fixable.rs:103:7 | LL | /// # CamelCaseThing | ^^^^^^^^^^^^^^ @@ -176,7 +176,7 @@ LL | /// # `CamelCaseThing` | ~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:104:22 + --> $DIR/doc-fixable.rs:105:22 | LL | /// Not a title #897 CamelCaseThing | ^^^^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL | /// Not a title #897 `CamelCaseThing` | ~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:105:5 + --> $DIR/doc-fixable.rs:106:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +198,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:112:5 + --> $DIR/doc-fixable.rs:113:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:125:5 + --> $DIR/doc-fixable.rs:126:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:136:43 + --> $DIR/doc-fixable.rs:137:43 | LL | /** E.g., serialization of an empty list: FooBar | ^^^^^^ @@ -231,7 +231,7 @@ LL | /** E.g., serialization of an empty list: `FooBar` | ~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:141:5 + --> $DIR/doc-fixable.rs:142:5 | LL | And BarQuz too. | ^^^^^^ @@ -242,7 +242,7 @@ LL | And `BarQuz` too. | ~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:142:1 + --> $DIR/doc-fixable.rs:143:1 | LL | be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | `be_sure_we_got_to_the_end_of_it` | error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:147:43 + --> $DIR/doc-fixable.rs:148:43 | LL | /** E.g., serialization of an empty list: FooBar | ^^^^^^ @@ -264,7 +264,7 @@ LL | /** E.g., serialization of an empty list: `FooBar` | ~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:152:5 + --> $DIR/doc-fixable.rs:153:5 | LL | And BarQuz too. | ^^^^^^ @@ -275,7 +275,7 @@ LL | And `BarQuz` too. | ~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:153:1 + --> $DIR/doc-fixable.rs:154:1 | LL | be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -286,7 +286,7 @@ LL | `be_sure_we_got_to_the_end_of_it` | error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:164:5 + --> $DIR/doc-fixable.rs:165:5 | LL | /// be_sure_we_got_to_the_end_of_it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -297,7 +297,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it` | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: item in documentation is missing backticks - --> $DIR/doc-fixable.rs:183:22 + --> $DIR/doc-fixable.rs:184:22 | LL | /// An iterator over mycrate::Collection's values. | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/doc/needless_doctest_main.rs b/tests/ui/doc/needless_doctest_main.rs new file mode 100644 index 000000000000..c941f0eb9abd --- /dev/null +++ b/tests/ui/doc/needless_doctest_main.rs @@ -0,0 +1,35 @@ +#![warn(clippy::needless_doctest_main)] +//! issue 10491: +//! ```rust,no_test +//! use std::collections::HashMap; +//! +//! fn main() { +//! let mut m = HashMap::new(); +//! m.insert(1u32, 2u32); +//! } +//! ``` +<<<<<<< HEAD +<<<<<<< HEAD +======= +//! +>>>>>>> 062b20990 (Ignore `main()` in `no_test` code fences) +======= +>>>>>>> a5d05f2f9 (run `cargo dev fmt`) + +/// some description here +/// ```rust,no_test +/// fn main() { +/// foo() +/// } +/// ``` +fn foo() {} +<<<<<<< HEAD +<<<<<<< HEAD + +fn main() {} +======= +>>>>>>> 062b20990 (Ignore `main()` in `no_test` code fences) +======= + +fn main() {} +>>>>>>> 867bd1538 (add main function to test itself) diff --git a/tests/ui/doc_unsafe.rs b/tests/ui/doc_unsafe.rs index 30674ce3708e..064d1272ad11 100644 --- a/tests/ui/doc_unsafe.rs +++ b/tests/ui/doc_unsafe.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(clippy::let_unit_value)] diff --git a/tests/ui/double_comparison.fixed b/tests/ui/double_comparison.fixed index bb6cdaa667d4..5ec2c77de2c1 100644 --- a/tests/ui/double_comparison.fixed +++ b/tests/ui/double_comparison.fixed @@ -1,4 +1,8 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(clippy::needless_if)] +======= +>>>>>>> e4f5d83fa (Fixed formatting.) fn main() { let x = 1; diff --git a/tests/ui/double_comparison.rs b/tests/ui/double_comparison.rs index 9a2a9068a28d..05a55d7373dd 100644 --- a/tests/ui/double_comparison.rs +++ b/tests/ui/double_comparison.rs @@ -1,4 +1,8 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(clippy::needless_if)] +======= +>>>>>>> e4f5d83fa (Fixed formatting.) fn main() { let x = 1; diff --git a/tests/ui/double_comparison.stderr b/tests/ui/double_comparison.stderr index 05ef4e25f7f8..4df1c28ac487 100644 --- a/tests/ui/double_comparison.stderr +++ b/tests/ui/double_comparison.stderr @@ -1,5 +1,5 @@ error: this binary expression can be simplified - --> $DIR/double_comparison.rs:6:8 + --> $DIR/double_comparison.rs:7:8 | LL | if x == y || x < y { | ^^^^^^^^^^^^^^^ help: try: `x <= y` @@ -7,43 +7,43 @@ LL | if x == y || x < y { = note: `-D clippy::double-comparisons` implied by `-D warnings` error: this binary expression can be simplified - --> $DIR/double_comparison.rs:9:8 + --> $DIR/double_comparison.rs:10:8 | LL | if x < y || x == y { | ^^^^^^^^^^^^^^^ help: try: `x <= y` error: this binary expression can be simplified - --> $DIR/double_comparison.rs:12:8 + --> $DIR/double_comparison.rs:13:8 | LL | if x == y || x > y { | ^^^^^^^^^^^^^^^ help: try: `x >= y` error: this binary expression can be simplified - --> $DIR/double_comparison.rs:15:8 + --> $DIR/double_comparison.rs:16:8 | LL | if x > y || x == y { | ^^^^^^^^^^^^^^^ help: try: `x >= y` error: this binary expression can be simplified - --> $DIR/double_comparison.rs:18:8 + --> $DIR/double_comparison.rs:19:8 | LL | if x < y || x > y { | ^^^^^^^^^^^^^^ help: try: `x != y` error: this binary expression can be simplified - --> $DIR/double_comparison.rs:21:8 + --> $DIR/double_comparison.rs:22:8 | LL | if x > y || x < y { | ^^^^^^^^^^^^^^ help: try: `x != y` error: this binary expression can be simplified - --> $DIR/double_comparison.rs:24:8 + --> $DIR/double_comparison.rs:25:8 | LL | if x <= y && x >= y { | ^^^^^^^^^^^^^^^^ help: try: `x == y` error: this binary expression can be simplified - --> $DIR/double_comparison.rs:27:8 + --> $DIR/double_comparison.rs:28:8 | LL | if x >= y && x <= y { | ^^^^^^^^^^^^^^^^ help: try: `x == y` diff --git a/tests/ui/drain_collect.fixed b/tests/ui/drain_collect.fixed new file mode 100644 index 000000000000..fe8e165ef288 --- /dev/null +++ b/tests/ui/drain_collect.fixed @@ -0,0 +1,86 @@ +//@run-rustfix + +#![deny(clippy::drain_collect)] +#![allow(dead_code)] + +use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; + +fn binaryheap(b: &mut BinaryHeap) -> BinaryHeap { + std::mem::take(b) +} + +fn binaryheap_dont_lint(b: &mut BinaryHeap) -> HashSet { + b.drain().collect() +} + +fn hashmap(b: &mut HashMap) -> HashMap { + std::mem::take(b) +} + +fn hashmap_dont_lint(b: &mut HashMap) -> Vec<(i32, i32)> { + b.drain().collect() +} + +fn hashset(b: &mut HashSet) -> HashSet { + std::mem::take(b) +} + +fn hashset_dont_lint(b: &mut HashSet) -> Vec { + b.drain().collect() +} + +fn vecdeque(b: &mut VecDeque) -> VecDeque { + std::mem::take(b) +} + +fn vecdeque_dont_lint(b: &mut VecDeque) -> HashSet { + b.drain(..).collect() +} + +fn vec(b: &mut Vec) -> Vec { + std::mem::take(b) +} + +fn vec2(b: &mut Vec) -> Vec { + std::mem::take(b) +} + +fn vec3(b: &mut Vec) -> Vec { + std::mem::take(b) +} + +fn vec4(b: &mut Vec) -> Vec { + std::mem::take(b) +} + +fn vec_no_reborrow() -> Vec { + let mut b = vec![1, 2, 3]; + std::mem::take(&mut b) +} + +fn vec_dont_lint(b: &mut Vec) -> HashSet { + b.drain(..).collect() +} + +fn string(b: &mut String) -> String { + std::mem::take(b) +} + +fn string_dont_lint(b: &mut String) -> HashSet { + b.drain(..).collect() +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5821fbbc3 (add test case for not whole length, move sugg into variable) +fn not_whole_length(v: &mut Vec) -> Vec { + v.drain(1..).collect() +} + +<<<<<<< HEAD +======= +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) +======= +>>>>>>> 5821fbbc3 (add test case for not whole length, move sugg into variable) +fn main() {} diff --git a/tests/ui/drain_collect.rs b/tests/ui/drain_collect.rs new file mode 100644 index 000000000000..335ee2d3f8aa --- /dev/null +++ b/tests/ui/drain_collect.rs @@ -0,0 +1,105 @@ +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) +//@run-rustfix + +#![deny(clippy::drain_collect)] +#![allow(dead_code)] +<<<<<<< HEAD +======= +#![deny(clippy::drain_collect)] +>>>>>>> 2748ab956 (new lint: `drain_collect`) +======= +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) + +use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; + +fn binaryheap(b: &mut BinaryHeap) -> BinaryHeap { + b.drain().collect() +} + +fn binaryheap_dont_lint(b: &mut BinaryHeap) -> HashSet { + b.drain().collect() +} + +fn hashmap(b: &mut HashMap) -> HashMap { + b.drain().collect() +} + +fn hashmap_dont_lint(b: &mut HashMap) -> Vec<(i32, i32)> { + b.drain().collect() +} + +fn hashset(b: &mut HashSet) -> HashSet { + b.drain().collect() +} + +fn hashset_dont_lint(b: &mut HashSet) -> Vec { + b.drain().collect() +} + +fn vecdeque(b: &mut VecDeque) -> VecDeque { + b.drain(..).collect() +} + +fn vecdeque_dont_lint(b: &mut VecDeque) -> HashSet { + b.drain(..).collect() +} + +fn vec(b: &mut Vec) -> Vec { + b.drain(..).collect() +} + +fn vec2(b: &mut Vec) -> Vec { + b.drain(0..).collect() +} + +fn vec3(b: &mut Vec) -> Vec { + b.drain(..b.len()).collect() +} + +fn vec4(b: &mut Vec) -> Vec { + b.drain(0..b.len()).collect() +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) +fn vec_no_reborrow() -> Vec { + let mut b = vec![1, 2, 3]; + b.drain(..).collect() +} + +<<<<<<< HEAD +======= +>>>>>>> 2748ab956 (new lint: `drain_collect`) +======= +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) +fn vec_dont_lint(b: &mut Vec) -> HashSet { + b.drain(..).collect() +} + +fn string(b: &mut String) -> String { + b.drain(..).collect() +} + +fn string_dont_lint(b: &mut String) -> HashSet { + b.drain(..).collect() +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5821fbbc3 (add test case for not whole length, move sugg into variable) +fn not_whole_length(v: &mut Vec) -> Vec { + v.drain(1..).collect() +} + +<<<<<<< HEAD +======= +>>>>>>> 2748ab956 (new lint: `drain_collect`) +======= +>>>>>>> 5821fbbc3 (add test case for not whole length, move sugg into variable) +fn main() {} diff --git a/tests/ui/drain_collect.stderr b/tests/ui/drain_collect.stderr new file mode 100644 index 000000000000..4e2bfd2fea14 --- /dev/null +++ b/tests/ui/drain_collect.stderr @@ -0,0 +1,149 @@ +error: you seem to be trying to move all elements into a new `BinaryHeap` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/drain_collect.rs:9:5 + | +LL | b.drain().collect() + | ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + | +note: the lint level is defined here + --> $DIR/drain_collect.rs:3:9 +======= + --> $DIR/drain_collect.rs:6:5 +======= + --> $DIR/drain_collect.rs:9:5 +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) + | +LL | b.drain().collect() + | ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + | +note: the lint level is defined here +<<<<<<< HEAD + --> $DIR/drain_collect.rs:1:9 +>>>>>>> 2748ab956 (new lint: `drain_collect`) +======= + --> $DIR/drain_collect.rs:3:9 +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) + | +LL | #![deny(clippy::drain_collect)] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: you seem to be trying to move all elements into a new `HashMap` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/drain_collect.rs:17:5 + | +LL | b.drain().collect() + | ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `HashSet` + --> $DIR/drain_collect.rs:25:5 + | +LL | b.drain().collect() + | ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` + --> $DIR/drain_collect.rs:33:5 + | +LL | b.drain(..).collect() + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` + --> $DIR/drain_collect.rs:41:5 + | +LL | b.drain(..).collect() + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` + --> $DIR/drain_collect.rs:45:5 + | +LL | b.drain(0..).collect() + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` + --> $DIR/drain_collect.rs:49:5 + | +LL | b.drain(..b.len()).collect() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` + --> $DIR/drain_collect.rs:53:5 + | +LL | b.drain(0..b.len()).collect() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` +======= + --> $DIR/drain_collect.rs:14:5 +======= + --> $DIR/drain_collect.rs:17:5 +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) + | +LL | b.drain().collect() + | ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `HashSet` + --> $DIR/drain_collect.rs:25:5 + | +LL | b.drain().collect() + | ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` + --> $DIR/drain_collect.rs:33:5 + | +LL | b.drain(..).collect() + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` + --> $DIR/drain_collect.rs:41:5 + | +LL | b.drain(..).collect() + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` + --> $DIR/drain_collect.rs:45:5 + | +LL | b.drain(0..).collect() + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` + --> $DIR/drain_collect.rs:49:5 + | +LL | b.drain(..b.len()).collect() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: you seem to be trying to move all elements into a new `Vec` + --> $DIR/drain_collect.rs:53:5 + | +LL | b.drain(0..b.len()).collect() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +<<<<<<< HEAD +error: you seem to be trying to move all elements into a new `String` +>>>>>>> 2748ab956 (new lint: `drain_collect`) +======= +error: you seem to be trying to move all elements into a new `Vec` +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) + --> $DIR/drain_collect.rs:58:5 + | +LL | b.drain(..).collect() + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(&mut b)` + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) +error: you seem to be trying to move all elements into a new `String` + --> $DIR/drain_collect.rs:66:5 + | +LL | b.drain(..).collect() + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)` + +error: aborting due to 10 previous errors +<<<<<<< HEAD +======= +error: aborting due to 9 previous errors +>>>>>>> 2748ab956 (new lint: `drain_collect`) +======= +>>>>>>> d2a6ec2d4 (take into account reborrowing when inserting `&mut` in sugg) + diff --git a/tests/ui/drop_forget_copy.rs b/tests/ui/drop_forget_copy.rs deleted file mode 100644 index a7276dd59f43..000000000000 --- a/tests/ui/drop_forget_copy.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![warn(clippy::drop_copy, clippy::forget_copy)] -#![allow(clippy::toplevel_ref_arg, clippy::drop_ref, clippy::forget_ref, unused_mut)] - -use std::mem::{drop, forget}; -use std::vec::Vec; - -#[derive(Copy, Clone)] -struct SomeStruct; - -struct AnotherStruct { - x: u8, - y: u8, - z: Vec, -} - -impl Clone for AnotherStruct { - fn clone(&self) -> AnotherStruct { - AnotherStruct { - x: self.x, - y: self.y, - z: self.z.clone(), - } - } -} - -fn main() { - let s1 = SomeStruct {}; - let s2 = s1; - let s3 = &s1; - let mut s4 = s1; - let ref s5 = s1; - - drop(s1); - drop(s2); - drop(s3); - drop(s4); - drop(s5); - - forget(s1); - forget(s2); - forget(s3); - forget(s4); - forget(s5); - - let a1 = AnotherStruct { - x: 255, - y: 0, - z: vec![1, 2, 3], - }; - let a2 = &a1; - let mut a3 = a1.clone(); - let ref a4 = a1; - let a5 = a1.clone(); - - drop(a2); - drop(a3); - drop(a4); - drop(a5); - - forget(a2); - let a3 = &a1; - forget(a3); - forget(a4); - let a5 = a1.clone(); - forget(a5); -} - -#[allow(unused)] -#[allow(clippy::unit_cmp)] -fn issue9482(x: u8) { - fn println_and(t: T) -> T { - println!("foo"); - t - } - - match x { - 0 => drop(println_and(12)), // Don't lint (copy type), we only care about side-effects - 1 => drop(println_and(String::new())), // Don't lint (no copy type), we only care about side-effects - 2 => { - drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block - }, - 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - 4 => drop(2), // Lint, not a fn/method call - _ => (), - } -} diff --git a/tests/ui/drop_forget_copy.stderr b/tests/ui/drop_forget_copy.stderr deleted file mode 100644 index 90bef1c3c439..000000000000 --- a/tests/ui/drop_forget_copy.stderr +++ /dev/null @@ -1,112 +0,0 @@ -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:33:5 - | -LL | drop(s1); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:33:10 - | -LL | drop(s1); - | ^^ - = note: `-D clippy::drop-copy` implied by `-D warnings` - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:34:5 - | -LL | drop(s2); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:34:10 - | -LL | drop(s2); - | ^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:36:5 - | -LL | drop(s4); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:36:10 - | -LL | drop(s4); - | ^^ - -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:39:5 - | -LL | forget(s1); - | ^^^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:39:12 - | -LL | forget(s1); - | ^^ - = note: `-D clippy::forget-copy` implied by `-D warnings` - -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:40:5 - | -LL | forget(s2); - | ^^^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:40:12 - | -LL | forget(s2); - | ^^ - -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:42:5 - | -LL | forget(s4); - | ^^^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:42:12 - | -LL | forget(s4); - | ^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:80:13 - | -LL | drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_forget_copy.rs:80:18 - | -LL | drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:82:14 - | -LL | 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_forget_copy.rs:82:19 - | -LL | 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:83:14 - | -LL | 4 => drop(2), // Lint, not a fn/method call - | ^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_forget_copy.rs:83:19 - | -LL | 4 => drop(2), // Lint, not a fn/method call - | ^ - -error: aborting due to 9 previous errors - diff --git a/tests/ui/drop_ref.rs b/tests/ui/drop_ref.rs deleted file mode 100644 index 10044e65f115..000000000000 --- a/tests/ui/drop_ref.rs +++ /dev/null @@ -1,97 +0,0 @@ -#![warn(clippy::drop_ref)] -#![allow(clippy::toplevel_ref_arg)] -#![allow(clippy::map_err_ignore)] -#![allow(clippy::unnecessary_wraps, clippy::drop_non_drop)] - -use std::mem::drop; - -struct SomeStruct; - -fn main() { - drop(&SomeStruct); - - let mut owned1 = SomeStruct; - drop(&owned1); - drop(&&owned1); - drop(&mut owned1); - drop(owned1); //OK - - let reference1 = &SomeStruct; - drop(reference1); - - let reference2 = &mut SomeStruct; - drop(reference2); - - let ref reference3 = SomeStruct; - drop(reference3); -} - -#[allow(dead_code)] -fn test_generic_fn_drop(val: T) { - drop(&val); - drop(val); //OK -} - -#[allow(dead_code)] -fn test_similarly_named_function() { - fn drop(_val: T) {} - drop(&SomeStruct); //OK; call to unrelated function which happens to have the same name - std::mem::drop(&SomeStruct); -} - -#[derive(Copy, Clone)] -pub struct Error; -fn produce_half_owl_error() -> Result<(), Error> { - Ok(()) -} - -fn produce_half_owl_ok() -> Result { - Ok(true) -} - -#[allow(dead_code)] -fn test_owl_result() -> Result<(), ()> { - produce_half_owl_error().map_err(|_| ())?; - produce_half_owl_ok().map(|_| ())?; - // the following should not be linted, - // we should not force users to use toilet closures - // to produce owl results when drop is more convenient - produce_half_owl_error().map_err(drop)?; - produce_half_owl_ok().map_err(drop)?; - Ok(()) -} - -#[allow(dead_code)] -fn test_owl_result_2() -> Result { - produce_half_owl_error().map_err(|_| ())?; - produce_half_owl_ok().map(|_| ())?; - // the following should not be linted, - // we should not force users to use toilet closures - // to produce owl results when drop is more convenient - produce_half_owl_error().map_err(drop)?; - produce_half_owl_ok().map(drop)?; - Ok(1) -} - -#[allow(unused)] -#[allow(clippy::unit_cmp)] -fn issue10122(x: u8) { - // This is a function which returns a reference and has a side-effect, which means - // that calling drop() on the function is considered an idiomatic way of achieving the side-effect - // in a match arm. - fn println_and(t: &T) -> &T { - println!("foo"); - t - } - - match x { - 0 => drop(println_and(&12)), // Don't lint (copy type), we only care about side-effects - 1 => drop(println_and(&String::new())), // Don't lint (no copy type), we only care about side-effects - 2 => { - drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block - }, - 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - 4 => drop(&2), // Lint, not a fn/method call - _ => (), - } -} diff --git a/tests/ui/drop_ref.stderr b/tests/ui/drop_ref.stderr deleted file mode 100644 index 293b9f6de832..000000000000 --- a/tests/ui/drop_ref.stderr +++ /dev/null @@ -1,147 +0,0 @@ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:11:5 - | -LL | drop(&SomeStruct); - | ^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:11:10 - | -LL | drop(&SomeStruct); - | ^^^^^^^^^^^ - = note: `-D clippy::drop-ref` implied by `-D warnings` - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:14:5 - | -LL | drop(&owned1); - | ^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:14:10 - | -LL | drop(&owned1); - | ^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:15:5 - | -LL | drop(&&owned1); - | ^^^^^^^^^^^^^^ - | -note: argument has type `&&SomeStruct` - --> $DIR/drop_ref.rs:15:10 - | -LL | drop(&&owned1); - | ^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:16:5 - | -LL | drop(&mut owned1); - | ^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/drop_ref.rs:16:10 - | -LL | drop(&mut owned1); - | ^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:20:5 - | -LL | drop(reference1); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:20:10 - | -LL | drop(reference1); - | ^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:23:5 - | -LL | drop(reference2); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/drop_ref.rs:23:10 - | -LL | drop(reference2); - | ^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:26:5 - | -LL | drop(reference3); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:26:10 - | -LL | drop(reference3); - | ^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:31:5 - | -LL | drop(&val); - | ^^^^^^^^^^ - | -note: argument has type `&T` - --> $DIR/drop_ref.rs:31:10 - | -LL | drop(&val); - | ^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:39:5 - | -LL | std::mem::drop(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:39:20 - | -LL | std::mem::drop(&SomeStruct); - | ^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:91:13 - | -LL | drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:91:18 - | -LL | drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:93:14 - | -LL | 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:93:19 - | -LL | 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:94:14 - | -LL | 4 => drop(&2), // Lint, not a fn/method call - | ^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:94:19 - | -LL | 4 => drop(&2), // Lint, not a fn/method call - | ^^ - -error: aborting due to 12 previous errors - diff --git a/tests/ui/duration_subsec.fixed b/tests/ui/duration_subsec.fixed index d92b8998e880..bfd30f0042d5 100644 --- a/tests/ui/duration_subsec.fixed +++ b/tests/ui/duration_subsec.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::needless_borrow)] #![warn(clippy::duration_subsec)] diff --git a/tests/ui/duration_subsec.rs b/tests/ui/duration_subsec.rs index 08da804996d1..860233f084f3 100644 --- a/tests/ui/duration_subsec.rs +++ b/tests/ui/duration_subsec.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::needless_borrow)] #![warn(clippy::duration_subsec)] diff --git a/tests/ui/else_if_without_else.rs b/tests/ui/else_if_without_else.rs index 879b3ac398e4..eb5e2266540c 100644 --- a/tests/ui/else_if_without_else.rs +++ b/tests/ui/else_if_without_else.rs @@ -43,7 +43,7 @@ fn main() { if bla1() { println!("if"); } else if bla2() { - //~ ERROR else if without else + //~^ ERROR: `if` expression with an `else if`, but without a final `else` println!("else if"); } @@ -52,7 +52,7 @@ fn main() { } else if bla2() { println!("else if 1"); } else if bla3() { - //~ ERROR else if without else + //~^ ERROR: `if` expression with an `else if`, but without a final `else` println!("else if 2"); } } diff --git a/tests/ui/else_if_without_else.stderr b/tests/ui/else_if_without_else.stderr index 90ccfb4fad64..11baf75441ae 100644 --- a/tests/ui/else_if_without_else.stderr +++ b/tests/ui/else_if_without_else.stderr @@ -3,7 +3,7 @@ error: `if` expression with an `else if`, but without a final `else` | LL | } else if bla2() { | ____________^ -LL | | //~ ERROR else if without else +LL | | LL | | println!("else if"); LL | | } | |_____^ @@ -16,7 +16,7 @@ error: `if` expression with an `else if`, but without a final `else` | LL | } else if bla3() { | ____________^ -LL | | //~ ERROR else if without else +LL | | LL | | println!("else if 2"); LL | | } | |_____^ diff --git a/tests/ui/empty_drop.fixed b/tests/ui/empty_drop.fixed index 2e1b768461ab..fd0a9a7081ea 100644 --- a/tests/ui/empty_drop.fixed +++ b/tests/ui/empty_drop.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::empty_drop)] #![allow(unused)] diff --git a/tests/ui/empty_drop.rs b/tests/ui/empty_drop.rs index 75232b0334df..6c15cb933027 100644 --- a/tests/ui/empty_drop.rs +++ b/tests/ui/empty_drop.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::empty_drop)] #![allow(unused)] diff --git a/tests/ui/empty_line_after_doc_comments.rs b/tests/ui/empty_line_after_doc_comments.rs new file mode 100644 index 000000000000..4e3cb87c6401 --- /dev/null +++ b/tests/ui/empty_line_after_doc_comments.rs @@ -0,0 +1,142 @@ +<<<<<<< HEAD +//@aux-build:proc_macro_attr.rs:proc-macro +<<<<<<< HEAD +// Flaky test, see https://github.com/rust-lang/rust/issues/113585. +//@ignore-32bit +//@ignore-64bit +======= +>>>>>>> 5bd97ac17 (Update tests) +======= +//@aux-build:proc_macro_attr.rs +>>>>>>> e4f5d83fa (Fixed formatting.) +#![warn(clippy::empty_line_after_doc_comments)] +#![allow(clippy::assertions_on_constants)] +#![feature(custom_inner_attributes)] +#![rustfmt::skip] + +#[macro_use] +extern crate proc_macro_attr; + +mod some_mod { + //! This doc comment should *NOT* produce a warning + + mod some_inner_mod { + fn some_noop() {} + } +} + +/// This should produce a warning + +fn with_doc_and_newline() { assert!(true)} + +// This should *NOT* produce a warning +#[crate_type = "lib"] + +/// some comment +fn with_one_newline_and_comment() { assert!(true) } + +// This should *NOT* produce a warning +#[crate_type = "lib"] +/// some comment +fn with_no_newline_and_comment() { assert!(true) } + + +// This should *NOT* produce a warning +#[crate_type = "lib"] + +fn with_one_newline() { assert!(true) } + +// This should *NOT* produce a warning +#[crate_type = "lib"] + + +fn with_two_newlines() { assert!(true) } + + +// This should *NOT* produce a warning +#[crate_type = "lib"] + +enum Baz { + One, + Two +} + +// This should *NOT* produce a warning +#[crate_type = "lib"] + +struct Foo { + one: isize, + two: isize +} + +// This should *NOT* produce a warning +#[crate_type = "lib"] + +mod foo { +} + +/// This doc comment should produce a warning + +/** This is also a doc comment and should produce a warning + */ + +// This should *NOT* produce a warning +#[allow(non_camel_case_types)] +#[allow(missing_docs)] +#[allow(missing_docs)] +fn three_attributes() { assert!(true) } + +// This should *NOT* produce a warning +#[doc = " +Returns the escaped value of the textual representation of + +"] +pub fn function() -> bool { + true +} + +// This should *NOT* produce a warning +#[derive(Clone, Copy)] +pub enum FooFighter { + Bar1, + + Bar2, + + Bar3, + + Bar4 +} + +// This should *NOT* produce a warning because the empty line is inside a block comment +#[crate_type = "lib"] +/* + +*/ +pub struct S; + +// This should *NOT* produce a warning +#[crate_type = "lib"] +/* test */ +pub struct T; + +// This should *NOT* produce a warning +// See https://github.com/rust-lang/rust-clippy/issues/5567 +#[fake_async_trait] +pub trait Bazz { + fn foo() -> Vec { + let _i = ""; + + + + vec![] + } +} + +#[derive(Clone, Copy)] +#[dummy(string = "first line + +second line +")] +pub struct Args; + +fn main() {} diff --git a/tests/ui/empty_line_after_doc_comments.stderr b/tests/ui/empty_line_after_doc_comments.stderr new file mode 100644 index 000000000000..2ca1b51679ed --- /dev/null +++ b/tests/ui/empty_line_after_doc_comments.stderr @@ -0,0 +1,36 @@ +error: found an empty line after a doc comment. Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`? + --> $DIR/empty_line_after_doc_comments.rs:18:1 + | +LL | / /// This should produce a warning +LL | | +LL | | fn with_doc_and_newline() { assert!(true)} + | |_ + | + = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings` + +error: found an empty line after a doc comment. Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`? + --> $DIR/empty_line_after_doc_comments.rs:68:1 + | +LL | / /// This doc comment should produce a warning +LL | | +LL | | /** This is also a doc comment and should produce a warning +LL | | */ +... | +LL | | #[allow(missing_docs)] +LL | | fn three_attributes() { assert!(true) } + | |_ + +error: found an empty line after a doc comment. Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`? + --> $DIR/empty_line_after_doc_comments.rs:70:1 + | +LL | / /** This is also a doc comment and should produce a warning +LL | | */ +LL | | +LL | | // This should *NOT* produce a warning +... | +LL | | #[allow(missing_docs)] +LL | | fn three_attributes() { assert!(true) } + | |_ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/empty_line_after_outer_attribute.rs b/tests/ui/empty_line_after_outer_attribute.rs index 697412c00275..2f106dbf336d 100644 --- a/tests/ui/empty_line_after_outer_attribute.rs +++ b/tests/ui/empty_line_after_outer_attribute.rs @@ -1,4 +1,14 @@ -// aux-build:proc_macro_attr.rs +<<<<<<< HEAD +//@aux-build:proc_macro_attr.rs:proc-macro +<<<<<<< HEAD +// Flaky test, see https://github.com/rust-lang/rust/issues/113585. +//@ignore-32bit +//@ignore-64bit +======= +>>>>>>> 5bd97ac17 (Update tests) +======= +//@aux-build:proc_macro_attr.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::empty_line_after_outer_attr)] #![allow(clippy::assertions_on_constants)] #![feature(custom_inner_attributes)] diff --git a/tests/ui/empty_loop.rs b/tests/ui/empty_loop.rs index 6a8e6b550c13..e07ff4d805d8 100644 --- a/tests/ui/empty_loop.rs +++ b/tests/ui/empty_loop.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::empty_loop)] diff --git a/tests/ui/empty_loop_no_std.rs b/tests/ui/empty_loop_no_std.rs index e742b396fcde..edac2a17acf2 100644 --- a/tests/ui/empty_loop_no_std.rs +++ b/tests/ui/empty_loop_no_std.rs @@ -1,5 +1,9 @@ -// compile-flags: -Clink-arg=-nostartfiles -// ignore-macos +//@compile-flags: -Clink-arg=-nostartfiles +<<<<<<< HEAD +//@ignore-target-apple +======= +//@ignore-macos +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::empty_loop)] #![feature(lang_items, start, libc)] diff --git a/tests/ui/empty_structs_with_brackets.fixed b/tests/ui/empty_structs_with_brackets.fixed index 80f07603b8d4..6fab30208393 100644 --- a/tests/ui/empty_structs_with_brackets.fixed +++ b/tests/ui/empty_structs_with_brackets.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::empty_structs_with_brackets)] #![allow(dead_code)] diff --git a/tests/ui/empty_structs_with_brackets.rs b/tests/ui/empty_structs_with_brackets.rs index 1d1ed4c76902..0caa3c49cd66 100644 --- a/tests/ui/empty_structs_with_brackets.rs +++ b/tests/ui/empty_structs_with_brackets.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::empty_structs_with_brackets)] #![allow(dead_code)] diff --git a/tests/ui/endian_bytes.rs b/tests/ui/endian_bytes.rs new file mode 100644 index 000000000000..d8a6c424cbdc --- /dev/null +++ b/tests/ui/endian_bytes.rs @@ -0,0 +1,231 @@ +#![allow(unused)] +#![allow(clippy::diverging_sub_expression)] +#![no_main] + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +macro_rules! fn_body { + () => { + 2u8.to_ne_bytes(); + 2i8.to_ne_bytes(); + 2u16.to_ne_bytes(); + 2i16.to_ne_bytes(); + 2u32.to_ne_bytes(); + 2i32.to_ne_bytes(); + 2u64.to_ne_bytes(); + 2i64.to_ne_bytes(); + 2u128.to_ne_bytes(); + 2i128.to_ne_bytes(); + 2.0f32.to_ne_bytes(); + 2.0f64.to_ne_bytes(); + 2usize.to_ne_bytes(); + 2isize.to_ne_bytes(); + u8::from_ne_bytes(todo!()); + i8::from_ne_bytes(todo!()); + u16::from_ne_bytes(todo!()); + i16::from_ne_bytes(todo!()); + u32::from_ne_bytes(todo!()); + i32::from_ne_bytes(todo!()); + u64::from_ne_bytes(todo!()); + i64::from_ne_bytes(todo!()); + u128::from_ne_bytes(todo!()); + i128::from_ne_bytes(todo!()); + usize::from_ne_bytes(todo!()); + isize::from_ne_bytes(todo!()); + f32::from_ne_bytes(todo!()); + f64::from_ne_bytes(todo!()); + + 2u8.to_le_bytes(); + 2i8.to_le_bytes(); + 2u16.to_le_bytes(); + 2i16.to_le_bytes(); + 2u32.to_le_bytes(); + 2i32.to_le_bytes(); + 2u64.to_le_bytes(); + 2i64.to_le_bytes(); + 2u128.to_le_bytes(); + 2i128.to_le_bytes(); + 2.0f32.to_le_bytes(); + 2.0f64.to_le_bytes(); + 2usize.to_le_bytes(); + 2isize.to_le_bytes(); + u8::from_le_bytes(todo!()); + i8::from_le_bytes(todo!()); + u16::from_le_bytes(todo!()); + i16::from_le_bytes(todo!()); + u32::from_le_bytes(todo!()); + i32::from_le_bytes(todo!()); + u64::from_le_bytes(todo!()); + i64::from_le_bytes(todo!()); + u128::from_le_bytes(todo!()); + i128::from_le_bytes(todo!()); + usize::from_le_bytes(todo!()); + isize::from_le_bytes(todo!()); + f32::from_le_bytes(todo!()); + f64::from_le_bytes(todo!()); + }; +} + +// bless breaks if I use fn_body too much (oops) +<<<<<<< HEAD +<<<<<<< HEAD +macro_rules! fn_body_smol { +======= +macro_rules! fn_body_small { +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +======= +macro_rules! fn_body_smol { +>>>>>>> 04b7cae37 (refine output) + () => { + 2u8.to_ne_bytes(); + u8::from_ne_bytes(todo!()); + + 2u8.to_le_bytes(); + u8::from_le_bytes(todo!()); + + 2u8.to_be_bytes(); + u8::from_be_bytes(todo!()); + }; +} + +#[rustfmt::skip] +<<<<<<< HEAD +#[warn(clippy::host_endian_bytes)] +fn host() { fn_body!(); } + +#[rustfmt::skip] +#[warn(clippy::little_endian_bytes)] +fn little() { fn_body!(); } + +#[rustfmt::skip] +#[warn(clippy::big_endian_bytes)] +fn big() { fn_body!(); } + +#[rustfmt::skip] +#[warn(clippy::host_endian_bytes)] +#[warn(clippy::big_endian_bytes)] +fn host_encourage_little() { fn_body_smol!(); } + +#[rustfmt::skip] +#[warn(clippy::host_endian_bytes)] +#[warn(clippy::little_endian_bytes)] +fn host_encourage_big() { fn_body_smol!(); } + +#[rustfmt::skip] +#[warn(clippy::host_endian_bytes)] +#[warn(clippy::little_endian_bytes)] +#[warn(clippy::big_endian_bytes)] +fn no_help() { fn_body_smol!(); } + +#[rustfmt::skip] +#[warn(clippy::little_endian_bytes)] +#[warn(clippy::big_endian_bytes)] +fn little_encourage_host() { fn_body_smol!(); } + +#[rustfmt::skip] +#[warn(clippy::host_endian_bytes)] +#[warn(clippy::little_endian_bytes)] +fn little_encourage_big() { fn_body_smol!(); } + +#[rustfmt::skip] +#[warn(clippy::big_endian_bytes)] +#[warn(clippy::little_endian_bytes)] +fn big_encourage_host() { fn_body_smol!(); } + +#[rustfmt::skip] +#[warn(clippy::host_endian_bytes)] +#[warn(clippy::big_endian_bytes)] +fn big_encourage_little() { fn_body_smol!(); } +======= +======= +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +#[warn(clippy::host_endian_bytes)] +fn host() { fn_body!(); } + +#[rustfmt::skip] +#[warn(clippy::little_endian_bytes)] +fn little() { fn_body!(); } + +#[rustfmt::skip] +#[warn(clippy::big_endian_bytes)] +fn big() { fn_body!(); } + +#[rustfmt::skip] +#[warn(clippy::host_endian_bytes)] +#[warn(clippy::big_endian_bytes)] +fn host_encourage_little() { fn_body_smol!(); } + +#[rustfmt::skip] +#[warn(clippy::host_endian_bytes)] +#[warn(clippy::little_endian_bytes)] +fn host_encourage_big() { fn_body_smol!(); } + +#[rustfmt::skip] +#[warn(clippy::host_endian_bytes)] +#[warn(clippy::little_endian_bytes)] +#[warn(clippy::big_endian_bytes)] +fn no_help() { fn_body_smol!(); } + +#[rustfmt::skip] +#[warn(clippy::little_endian_bytes)] +#[warn(clippy::big_endian_bytes)] +fn little_encourage_host() { fn_body_smol!(); } + +#[rustfmt::skip] +#[warn(clippy::host_endian_bytes)] +#[warn(clippy::little_endian_bytes)] +fn little_encourage_big() { fn_body_smol!(); } + +#[rustfmt::skip] +#[warn(clippy::big_endian_bytes)] +#[warn(clippy::little_endian_bytes)] +<<<<<<< HEAD +<<<<<<< HEAD +fn big_no_help() { + 2u8.to_be_bytes(); + 2i8.to_be_bytes(); + 2u16.to_be_bytes(); + 2i16.to_be_bytes(); + 2u32.to_be_bytes(); + 2i32.to_be_bytes(); + 2u64.to_be_bytes(); + 2i64.to_be_bytes(); + 2u128.to_be_bytes(); + 2i128.to_be_bytes(); + 2usize.to_be_bytes(); + 2isize.to_be_bytes(); + 2.0f32.to_be_bytes(); + 2.0f64.to_be_bytes(); + u8::from_be_bytes(todo!()); + i8::from_be_bytes(todo!()); + u16::from_be_bytes(todo!()); + i16::from_be_bytes(todo!()); + u32::from_be_bytes(todo!()); + i32::from_be_bytes(todo!()); + u64::from_be_bytes(todo!()); + i64::from_be_bytes(todo!()); + u128::from_be_bytes(todo!()); + i128::from_be_bytes(todo!()); + usize::from_be_bytes(todo!()); + isize::from_be_bytes(todo!()); + f32::from_be_bytes(todo!()); + f64::from_be_bytes(todo!()); +} +>>>>>>> 3ab6aeefb (`to_xx_bytes` implemented, `from_xx_bytes` todo) +======= +fn big_encourage_host() { fn_body_small!(); } +======= +fn big_encourage_host() { fn_body_smol!(); } +>>>>>>> 04b7cae37 (refine output) + +#[rustfmt::skip] +#[warn(clippy::host_endian_bytes)] +#[warn(clippy::big_endian_bytes)] +<<<<<<< HEAD +fn big_encourage_little() { fn_body_small!(); } +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) +======= +fn big_encourage_little() { fn_body_smol!(); } +>>>>>>> 04b7cae37 (refine output) diff --git a/tests/ui/endian_bytes.stderr b/tests/ui/endian_bytes.stderr new file mode 100644 index 000000000000..a5def4e6e0ab --- /dev/null +++ b/tests/ui/endian_bytes.stderr @@ -0,0 +1,2325 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +error: usage of the `u8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:7:9 + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: `-D clippy::host-endian-bytes` implied by `-D warnings` + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:8:9 + | +LL | 2i8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u16::to_ne_bytes` method + --> $DIR/endian_bytes.rs:9:9 + | +LL | 2u16.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i16::to_ne_bytes` method + --> $DIR/endian_bytes.rs:10:9 + | +LL | 2i16.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u32::to_ne_bytes` method + --> $DIR/endian_bytes.rs:11:9 + | +LL | 2u32.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i32::to_ne_bytes` method + --> $DIR/endian_bytes.rs:12:9 + | +LL | 2i32.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u64::to_ne_bytes` method + --> $DIR/endian_bytes.rs:13:9 + | +LL | 2u64.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i64::to_ne_bytes` method + --> $DIR/endian_bytes.rs:14:9 + | +LL | 2i64.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u128::to_ne_bytes` method + --> $DIR/endian_bytes.rs:15:9 + | +LL | 2u128.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i128::to_ne_bytes` method + --> $DIR/endian_bytes.rs:16:9 + | +LL | 2i128.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `f32::to_ne_bytes` method + --> $DIR/endian_bytes.rs:17:9 + | +LL | 2.0f32.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `f64::to_ne_bytes` method + --> $DIR/endian_bytes.rs:18:9 + | +LL | 2.0f64.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `usize::to_ne_bytes` method + --> $DIR/endian_bytes.rs:19:9 + | +LL | 2usize.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `isize::to_ne_bytes` method + --> $DIR/endian_bytes.rs:20:9 + | +LL | 2isize.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:21:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i8::from_ne_bytes` + --> $DIR/endian_bytes.rs:22:9 + | +LL | i8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u16::from_ne_bytes` + --> $DIR/endian_bytes.rs:23:9 + | +LL | u16::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i16::from_ne_bytes` + --> $DIR/endian_bytes.rs:24:9 + | +LL | i16::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u32::from_ne_bytes` + --> $DIR/endian_bytes.rs:25:9 + | +LL | u32::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i32::from_ne_bytes` + --> $DIR/endian_bytes.rs:26:9 + | +LL | i32::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u64::from_ne_bytes` + --> $DIR/endian_bytes.rs:27:9 + | +LL | u64::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i64::from_ne_bytes` + --> $DIR/endian_bytes.rs:28:9 + | +LL | i64::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u128::from_ne_bytes` + --> $DIR/endian_bytes.rs:29:9 + | +LL | u128::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i128::from_ne_bytes` + --> $DIR/endian_bytes.rs:30:9 + | +LL | i128::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `usize::from_ne_bytes` + --> $DIR/endian_bytes.rs:31:9 + | +LL | usize::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `isize::from_ne_bytes` + --> $DIR/endian_bytes.rs:32:9 + | +LL | isize::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `f32::from_ne_bytes` + --> $DIR/endian_bytes.rs:33:9 + | +LL | f32::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `f64::from_ne_bytes` + --> $DIR/endian_bytes.rs:34:9 + | +LL | f64::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:36:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: `-D clippy::little-endian-bytes` implied by `-D warnings` + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i8::to_le_bytes` method + --> $DIR/endian_bytes.rs:37:9 + | +LL | 2i8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u16::to_le_bytes` method + --> $DIR/endian_bytes.rs:38:9 + | +LL | 2u16.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i16::to_le_bytes` method + --> $DIR/endian_bytes.rs:39:9 + | +LL | 2i16.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u32::to_le_bytes` method + --> $DIR/endian_bytes.rs:40:9 + | +LL | 2u32.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i32::to_le_bytes` method + --> $DIR/endian_bytes.rs:41:9 + | +LL | 2i32.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u64::to_le_bytes` method + --> $DIR/endian_bytes.rs:42:9 + | +LL | 2u64.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i64::to_le_bytes` method + --> $DIR/endian_bytes.rs:43:9 + | +LL | 2i64.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u128::to_le_bytes` method + --> $DIR/endian_bytes.rs:44:9 + | +LL | 2u128.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i128::to_le_bytes` method + --> $DIR/endian_bytes.rs:45:9 + | +LL | 2i128.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `f32::to_le_bytes` method + --> $DIR/endian_bytes.rs:46:9 + | +LL | 2.0f32.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `f64::to_le_bytes` method + --> $DIR/endian_bytes.rs:47:9 + | +LL | 2.0f64.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `usize::to_le_bytes` method + --> $DIR/endian_bytes.rs:48:9 + | +LL | 2usize.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `isize::to_le_bytes` method + --> $DIR/endian_bytes.rs:49:9 + | +LL | 2isize.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:50:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i8::from_le_bytes` + --> $DIR/endian_bytes.rs:51:9 + | +LL | i8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u16::from_le_bytes` + --> $DIR/endian_bytes.rs:52:9 + | +LL | u16::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i16::from_le_bytes` + --> $DIR/endian_bytes.rs:53:9 + | +LL | i16::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u32::from_le_bytes` + --> $DIR/endian_bytes.rs:54:9 + | +LL | u32::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i32::from_le_bytes` + --> $DIR/endian_bytes.rs:55:9 + | +LL | i32::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u64::from_le_bytes` + --> $DIR/endian_bytes.rs:56:9 + | +LL | u64::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i64::from_le_bytes` + --> $DIR/endian_bytes.rs:57:9 + | +LL | i64::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u128::from_le_bytes` + --> $DIR/endian_bytes.rs:58:9 + | +LL | u128::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i128::from_le_bytes` + --> $DIR/endian_bytes.rs:59:9 + | +LL | i128::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `usize::from_le_bytes` + --> $DIR/endian_bytes.rs:60:9 + | +LL | usize::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `isize::from_le_bytes` + --> $DIR/endian_bytes.rs:61:9 + | +LL | isize::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `f32::from_le_bytes` + --> $DIR/endian_bytes.rs:62:9 + | +LL | f32::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `f64::from_le_bytes` + --> $DIR/endian_bytes.rs:63:9 + | +LL | f64::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:70:9 + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:71:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_be_bytes` method + --> $DIR/endian_bytes.rs:76:9 + | +LL | 2u8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_le_bytes` instead + = note: `-D clippy::big-endian-bytes` implied by `-D warnings` + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_be_bytes` + --> $DIR/endian_bytes.rs:77:9 + | +LL | u8::from_be_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:70:9 + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:71:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:73:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:74:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:70:9 + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:71:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:73:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:74:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_be_bytes` method + --> $DIR/endian_bytes.rs:76:9 + | +LL | 2u8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_be_bytes` + --> $DIR/endian_bytes.rs:77:9 + | +LL | u8::from_be_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:73:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:74:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_be_bytes` method + --> $DIR/endian_bytes.rs:76:9 + | +LL | 2u8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_be_bytes` + --> $DIR/endian_bytes.rs:77:9 + | +LL | u8::from_be_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:70:9 + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:71:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:73:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:74:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:73:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:74:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_be_bytes` method + --> $DIR/endian_bytes.rs:76:9 + | +LL | 2u8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_be_bytes` + --> $DIR/endian_bytes.rs:77:9 + | +LL | u8::from_be_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:70:9 + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:71:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_be_bytes` method + --> $DIR/endian_bytes.rs:76:9 + | +LL | 2u8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_be_bytes` + --> $DIR/endian_bytes.rs:77:9 + | +LL | u8::from_be_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 86 previous errors +======= +error: use of the method `from_ne_bytes` + --> $DIR/endian_bytes.rs:6:11 +======= +error: usage of the method `to_ne_bytes` +======= +error: usage of the `u8::to_ne_bytes` method +>>>>>>> 04b7cae37 (refine output) + --> $DIR/endian_bytes.rs:7:9 +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: `-D clippy::host-endian-bytes` implied by `-D warnings` + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:8:9 + | +LL | 2i8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u16::to_ne_bytes` method + --> $DIR/endian_bytes.rs:9:9 + | +LL | 2u16.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i16::to_ne_bytes` method + --> $DIR/endian_bytes.rs:10:9 + | +LL | 2i16.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u32::to_ne_bytes` method + --> $DIR/endian_bytes.rs:11:9 + | +LL | 2u32.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i32::to_ne_bytes` method + --> $DIR/endian_bytes.rs:12:9 + | +LL | 2i32.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u64::to_ne_bytes` method + --> $DIR/endian_bytes.rs:13:9 + | +LL | 2u64.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i64::to_ne_bytes` method + --> $DIR/endian_bytes.rs:14:9 + | +LL | 2i64.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u128::to_ne_bytes` method + --> $DIR/endian_bytes.rs:15:9 + | +LL | 2u128.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i128::to_ne_bytes` method + --> $DIR/endian_bytes.rs:16:9 + | +LL | 2i128.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `f32::to_ne_bytes` method + --> $DIR/endian_bytes.rs:17:9 + | +LL | 2.0f32.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `f64::to_ne_bytes` method + --> $DIR/endian_bytes.rs:18:9 + | +LL | 2.0f64.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `usize::to_ne_bytes` method + --> $DIR/endian_bytes.rs:19:9 + | +LL | 2usize.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `isize::to_ne_bytes` method + --> $DIR/endian_bytes.rs:20:9 + | +LL | 2isize.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:21:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i8::from_ne_bytes` + --> $DIR/endian_bytes.rs:22:9 + | +LL | i8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u16::from_ne_bytes` + --> $DIR/endian_bytes.rs:23:9 + | +LL | u16::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i16::from_ne_bytes` + --> $DIR/endian_bytes.rs:24:9 + | +LL | i16::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u32::from_ne_bytes` + --> $DIR/endian_bytes.rs:25:9 + | +LL | u32::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i32::from_ne_bytes` + --> $DIR/endian_bytes.rs:26:9 + | +LL | i32::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u64::from_ne_bytes` + --> $DIR/endian_bytes.rs:27:9 + | +LL | u64::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i64::from_ne_bytes` + --> $DIR/endian_bytes.rs:28:9 + | +LL | i64::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u128::from_ne_bytes` + --> $DIR/endian_bytes.rs:29:9 + | +LL | u128::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i128::from_ne_bytes` + --> $DIR/endian_bytes.rs:30:9 + | +LL | i128::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `usize::from_ne_bytes` + --> $DIR/endian_bytes.rs:31:9 + | +LL | usize::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `isize::from_ne_bytes` + --> $DIR/endian_bytes.rs:32:9 + | +LL | isize::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `f32::from_ne_bytes` + --> $DIR/endian_bytes.rs:33:9 + | +LL | f32::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `f64::from_ne_bytes` + --> $DIR/endian_bytes.rs:34:9 + | +LL | f64::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host() { fn_body!(); } + | ---------- in this macro invocation + | + = help: specify the desired endianness explicitly + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:36:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: `-D clippy::little-endian-bytes` implied by `-D warnings` + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i8::to_le_bytes` method + --> $DIR/endian_bytes.rs:37:9 + | +LL | 2i8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u16::to_le_bytes` method + --> $DIR/endian_bytes.rs:38:9 + | +LL | 2u16.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i16::to_le_bytes` method + --> $DIR/endian_bytes.rs:39:9 + | +LL | 2i16.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u32::to_le_bytes` method + --> $DIR/endian_bytes.rs:40:9 + | +LL | 2u32.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i32::to_le_bytes` method + --> $DIR/endian_bytes.rs:41:9 + | +LL | 2i32.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u64::to_le_bytes` method + --> $DIR/endian_bytes.rs:42:9 + | +LL | 2u64.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i64::to_le_bytes` method + --> $DIR/endian_bytes.rs:43:9 + | +LL | 2i64.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u128::to_le_bytes` method + --> $DIR/endian_bytes.rs:44:9 + | +LL | 2u128.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `i128::to_le_bytes` method + --> $DIR/endian_bytes.rs:45:9 + | +LL | 2i128.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `f32::to_le_bytes` method + --> $DIR/endian_bytes.rs:46:9 + | +LL | 2.0f32.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `f64::to_le_bytes` method + --> $DIR/endian_bytes.rs:47:9 + | +LL | 2.0f64.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `usize::to_le_bytes` method + --> $DIR/endian_bytes.rs:48:9 + | +LL | 2usize.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `isize::to_le_bytes` method + --> $DIR/endian_bytes.rs:49:9 + | +LL | 2isize.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:50:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i8::from_le_bytes` + --> $DIR/endian_bytes.rs:51:9 + | +LL | i8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u16::from_le_bytes` + --> $DIR/endian_bytes.rs:52:9 + | +LL | u16::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i16::from_le_bytes` + --> $DIR/endian_bytes.rs:53:9 + | +LL | i16::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u32::from_le_bytes` + --> $DIR/endian_bytes.rs:54:9 + | +LL | u32::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i32::from_le_bytes` + --> $DIR/endian_bytes.rs:55:9 + | +LL | i32::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u64::from_le_bytes` + --> $DIR/endian_bytes.rs:56:9 + | +LL | u64::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i64::from_le_bytes` + --> $DIR/endian_bytes.rs:57:9 + | +LL | i64::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u128::from_le_bytes` + --> $DIR/endian_bytes.rs:58:9 + | +LL | u128::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `i128::from_le_bytes` + --> $DIR/endian_bytes.rs:59:9 + | +LL | i128::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `usize::from_le_bytes` + --> $DIR/endian_bytes.rs:60:9 + | +LL | usize::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `isize::from_le_bytes` + --> $DIR/endian_bytes.rs:61:9 + | +LL | isize::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `f32::from_le_bytes` + --> $DIR/endian_bytes.rs:62:9 + | +LL | f32::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `f64::from_le_bytes` + --> $DIR/endian_bytes.rs:63:9 + | +LL | f64::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little() { fn_body!(); } + | ---------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:70:9 + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:71:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_be_bytes` method + --> $DIR/endian_bytes.rs:76:9 + | +LL | 2u8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_le_bytes` instead + = note: `-D clippy::big-endian-bytes` implied by `-D warnings` + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_be_bytes` + --> $DIR/endian_bytes.rs:77:9 + | +LL | u8::from_be_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:70:9 + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:71:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:73:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:74:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn host_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:70:9 + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:71:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:73:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:74:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_be_bytes` method + --> $DIR/endian_bytes.rs:76:9 + | +LL | 2u8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_be_bytes` + --> $DIR/endian_bytes.rs:77:9 + | +LL | u8::from_be_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn no_help() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:73:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:74:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_be_bytes` method + --> $DIR/endian_bytes.rs:76:9 + | +LL | 2u8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_be_bytes` + --> $DIR/endian_bytes.rs:77:9 + | +LL | u8::from_be_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:70:9 + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:71:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:73:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:74:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn little_encourage_big() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_be_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_le_bytes` method + --> $DIR/endian_bytes.rs:73:9 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_le_bytes` + --> $DIR/endian_bytes.rs:74:9 + | +LL | u8::from_le_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_be_bytes` method + --> $DIR/endian_bytes.rs:76:9 + | +LL | 2u8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_be_bytes` + --> $DIR/endian_bytes.rs:77:9 + | +LL | u8::from_be_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_host() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use the native endianness instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_ne_bytes` method + --> $DIR/endian_bytes.rs:70:9 + | +LL | 2u8.to_ne_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_ne_bytes` + --> $DIR/endian_bytes.rs:71:9 + | +LL | u8::from_ne_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the `u8::to_be_bytes` method + --> $DIR/endian_bytes.rs:76:9 + | +LL | 2u8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::to_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of the function `u8::from_be_bytes` + --> $DIR/endian_bytes.rs:77:9 + | +LL | u8::from_be_bytes(todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn big_encourage_little() { fn_body_smol!(); } + | --------------- in this macro invocation + | + = help: use `u8::from_le_bytes` instead + = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) + +<<<<<<< HEAD +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:73:5 + | +LL | 2u32.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^ + | + = help: use `to_le_bytes` instead + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:74:5 + | +LL | 2i32.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^ + | + = help: use `to_le_bytes` instead + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:75:5 + | +LL | 2u64.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^ + | + = help: use `to_le_bytes` instead + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:76:5 + | +LL | 2i64.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^ + | + = help: use `to_le_bytes` instead + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:77:5 + | +LL | 2u128.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^ + | + = help: use `to_le_bytes` instead + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:78:5 + | +LL | 2i128.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^ + | + = help: use `to_le_bytes` instead + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:79:5 + | +LL | 2.0f32.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: use `to_le_bytes` instead + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:80:5 + | +LL | 2.0f64.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: use `to_le_bytes` instead + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:81:5 + | +LL | 2usize.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: use `to_le_bytes` instead + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:82:5 + | +LL | 2isize.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: use `to_le_bytes` instead + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:102:5 + | +LL | 2u8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:103:5 + | +LL | 2i8.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:104:5 + | +LL | 2u16.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:105:5 + | +LL | 2i16.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:106:5 + | +LL | 2u32.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:107:5 + | +LL | 2i32.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:108:5 + | +LL | 2u64.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:109:5 + | +LL | 2i64.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:110:5 + | +LL | 2u128.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:111:5 + | +LL | 2i128.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:112:5 + | +LL | 2usize.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:113:5 + | +LL | 2isize.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:114:5 + | +LL | 2.0f32.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_le_bytes` + --> $DIR/endian_bytes.rs:115:5 + | +LL | 2.0f64.to_le_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:135:5 + | +LL | 2u8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:136:5 + | +LL | 2i8.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:137:5 + | +LL | 2u16.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:138:5 + | +LL | 2i16.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:139:5 + | +LL | 2u32.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:140:5 + | +LL | 2i32.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:141:5 + | +LL | 2u64.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:142:5 + | +LL | 2i64.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:143:5 + | +LL | 2u128.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:144:5 + | +LL | 2i128.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:145:5 + | +LL | 2usize.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:146:5 + | +LL | 2isize.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:147:5 + | +LL | 2.0f32.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: use of the method `to_be_bytes` + --> $DIR/endian_bytes.rs:148:5 + | +LL | 2.0f64.to_be_bytes(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 145 previous errors +>>>>>>> 3ab6aeefb (`to_xx_bytes` implemented, `from_xx_bytes` todo) +======= +error: aborting due to 86 previous errors +>>>>>>> 97a0ccc1d (implement `host_endian_bytes` and the other two) + diff --git a/tests/ui/entry.fixed b/tests/ui/entry.fixed index dbe09e0ff3c6..7e82390605cc 100644 --- a/tests/ui/entry.fixed +++ b/tests/ui/entry.fixed @@ -1,5 +1,5 @@ -// needs-asm-support -// run-rustfix +//@needs-asm-support +//@run-rustfix #![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)] #![warn(clippy::map_entry)] diff --git a/tests/ui/entry.rs b/tests/ui/entry.rs index 30fed34fc5de..742c93225357 100644 --- a/tests/ui/entry.rs +++ b/tests/ui/entry.rs @@ -1,5 +1,5 @@ -// needs-asm-support -// run-rustfix +//@needs-asm-support +//@run-rustfix #![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)] #![warn(clippy::map_entry)] diff --git a/tests/ui/entry.stderr b/tests/ui/entry.stderr index 2c4c49d2522c..e8a003e9cf67 100644 --- a/tests/ui/entry.stderr +++ b/tests/ui/entry.stderr @@ -4,7 +4,7 @@ error: usage of `contains_key` followed by `insert` on a `HashMap` LL | / if !m.contains_key(&k) { LL | | m.insert(k, v); LL | | } - | |_____^ help: try this: `m.entry(k).or_insert(v);` + | |_____^ help: try: `m.entry(k).or_insert(v);` | = note: `-D clippy::map-entry` implied by `-D warnings` @@ -20,7 +20,7 @@ LL | | } LL | | } | |_____^ | -help: try this +help: try | LL ~ m.entry(k).or_insert_with(|| { LL + if true { @@ -43,7 +43,7 @@ LL | | }; LL | | } | |_____^ | -help: try this +help: try | LL ~ m.entry(k).or_insert_with(|| { LL + if true { @@ -66,7 +66,7 @@ LL | | } LL | | } | |_____^ | -help: try this +help: try | LL ~ if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { LL + if true { @@ -87,7 +87,7 @@ LL | | m.insert(k, v); LL | | } | |_____^ | -help: try this +help: try | LL ~ m.entry(k).or_insert_with(|| { LL + foo(); @@ -107,7 +107,7 @@ LL | | }; LL | | } | |_____^ | -help: try this +help: try | LL ~ m.entry(k).or_insert_with(|| { LL + match 0 { @@ -133,7 +133,7 @@ LL | | }; LL | | } | |_____^ | -help: try this +help: try | LL ~ if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { LL + match 0 { @@ -157,7 +157,7 @@ LL | | } LL | | } | |_____^ | -help: try this +help: try | LL ~ m.entry(k).or_insert_with(|| { LL + foo(); @@ -192,7 +192,7 @@ error: usage of `contains_key` followed by `insert` on a `HashMap` LL | / if !m.contains_key(&m!(k)) { LL | | m.insert(m!(k), m!(v)); LL | | } - | |_____^ help: try this: `m.entry(m!(k)).or_insert_with(|| m!(v));` + | |_____^ help: try: `m.entry(m!(k)).or_insert_with(|| m!(v));` error: usage of `contains_key` followed by `insert` on a `HashMap` --> $DIR/entry.rs:152:5 @@ -204,7 +204,7 @@ LL | | m.insert(k, v); LL | | } | |_____^ | -help: try this +help: try | LL ~ m.entry(k).or_insert_with(|| { LL + let x = (String::new(), String::new()); diff --git a/tests/ui/entry_btree.fixed b/tests/ui/entry_btree.fixed index 94979104556b..3baaacffd20d 100644 --- a/tests/ui/entry_btree.fixed +++ b/tests/ui/entry_btree.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_entry)] #![allow(dead_code)] diff --git a/tests/ui/entry_btree.rs b/tests/ui/entry_btree.rs index 080c1d959e89..770e8e91da23 100644 --- a/tests/ui/entry_btree.rs +++ b/tests/ui/entry_btree.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_entry)] #![allow(dead_code)] diff --git a/tests/ui/entry_btree.stderr b/tests/ui/entry_btree.stderr index 5c6fcdf1a28c..8f41581d6b6d 100644 --- a/tests/ui/entry_btree.stderr +++ b/tests/ui/entry_btree.stderr @@ -8,7 +8,7 @@ LL | | } | |_____^ | = note: `-D clippy::map-entry` implied by `-D warnings` -help: try this +help: try | LL ~ if let std::collections::btree_map::Entry::Vacant(e) = m.entry(k) { LL + e.insert(v); diff --git a/tests/ui/entry_with_else.fixed b/tests/ui/entry_with_else.fixed index 2332fa6313ff..71fe04fd6484 100644 --- a/tests/ui/entry_with_else.fixed +++ b/tests/ui/entry_with_else.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)] #![warn(clippy::map_entry)] diff --git a/tests/ui/entry_with_else.rs b/tests/ui/entry_with_else.rs index 2ff0c038efe2..80f74649a603 100644 --- a/tests/ui/entry_with_else.rs +++ b/tests/ui/entry_with_else.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)] #![warn(clippy::map_entry)] diff --git a/tests/ui/entry_with_else.stderr b/tests/ui/entry_with_else.stderr index e0f6671b460e..0d0eb964937e 100644 --- a/tests/ui/entry_with_else.stderr +++ b/tests/ui/entry_with_else.stderr @@ -9,7 +9,7 @@ LL | | } | |_____^ | = note: `-D clippy::map-entry` implied by `-D warnings` -help: try this +help: try | LL ~ match m.entry(k) { LL + std::collections::hash_map::Entry::Vacant(e) => { @@ -31,7 +31,7 @@ LL | | m.insert(k, v2); LL | | } | |_____^ | -help: try this +help: try | LL ~ match m.entry(k) { LL + std::collections::hash_map::Entry::Occupied(mut e) => { @@ -53,7 +53,7 @@ LL | | foo(); LL | | } | |_____^ | -help: try this +help: try | LL ~ if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) { LL + e.insert(v); @@ -72,7 +72,7 @@ LL | | m.insert(k, v); LL | | } | |_____^ | -help: try this +help: try | LL ~ if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) { LL + e.insert(v); @@ -91,7 +91,7 @@ LL | | m.insert(k, v2); LL | | } | |_____^ | -help: try this +help: try | LL ~ match m.entry(k) { LL + std::collections::hash_map::Entry::Vacant(e) => { @@ -113,7 +113,7 @@ LL | | m.insert(k, v) LL | | }; | |_____^ | -help: try this +help: try | LL ~ match m.entry(k) { LL + std::collections::hash_map::Entry::Occupied(mut e) => { @@ -137,7 +137,7 @@ LL | | None LL | | }; | |_____^ | -help: try this +help: try | LL ~ if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) { LL + foo(); diff --git a/tests/ui/enum_clike_unportable_variant.rs b/tests/ui/enum_clike_unportable_variant.rs index 7d6842f5b542..31ff6d78b22f 100644 --- a/tests/ui/enum_clike_unportable_variant.rs +++ b/tests/ui/enum_clike_unportable_variant.rs @@ -1,4 +1,8 @@ -// ignore-x86 +<<<<<<< HEAD +//@ignore-target-x86 +======= +//@ignore-x86 +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::enum_clike_unportable_variant)] #![allow(unused, non_upper_case_globals)] diff --git a/tests/ui/enum_glob_use.fixed b/tests/ui/enum_glob_use.fixed index a98216758bb9..419370ffb1d2 100644 --- a/tests/ui/enum_glob_use.fixed +++ b/tests/ui/enum_glob_use.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::enum_glob_use)] #![allow(unused)] diff --git a/tests/ui/enum_glob_use.rs b/tests/ui/enum_glob_use.rs index 5d929c9731d3..645ed98325c9 100644 --- a/tests/ui/enum_glob_use.rs +++ b/tests/ui/enum_glob_use.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::enum_glob_use)] #![allow(unused)] diff --git a/tests/ui/enum_variants.rs b/tests/ui/enum_variants.rs index efed12ee2ef6..531652a0e002 100644 --- a/tests/ui/enum_variants.rs +++ b/tests/ui/enum_variants.rs @@ -179,4 +179,14 @@ mod issue9018 { } } +mod allow_attributes_on_variants { + enum Enum { + #[allow(clippy::enum_variant_names)] + EnumStartsWith, + #[allow(clippy::enum_variant_names)] + EndsWithEnum, + Foo, + } +} + fn main() {} diff --git a/tests/ui/eprint_with_newline.rs b/tests/ui/eprint_with_newline.rs index de5e121be877..8389806c838e 100644 --- a/tests/ui/eprint_with_newline.rs +++ b/tests/ui/eprint_with_newline.rs @@ -44,7 +44,7 @@ fn main() { // Don't warn on CRLF (#4208) eprint!("\r\n"); eprint!("foo\r\n"); - eprint!("\\r\n"); //~ ERROR + eprint!("\\r\n"); eprint!("foo\rbar\n"); // Ignore expanded format strings diff --git a/tests/ui/eprint_with_newline.stderr b/tests/ui/eprint_with_newline.stderr index 0eefb9f0ca97..0a6bdf15df8e 100644 --- a/tests/ui/eprint_with_newline.stderr +++ b/tests/ui/eprint_with_newline.stderr @@ -62,13 +62,13 @@ LL + eprintln!(); error: using `eprint!()` with a format string that ends in a single newline --> $DIR/eprint_with_newline.rs:28:5 | -LL | eprint!("//n"); // should fail +LL | eprint!("///n"); // should fail | ^^^^^^^^^^^^^^^ | help: use `eprintln!` instead | -LL - eprint!("//n"); // should fail -LL + eprintln!("/"); // should fail +LL - eprint!("///n"); // should fail +LL + eprintln!("//"); // should fail | error: using `eprint!()` with a format string that ends in a single newline @@ -104,13 +104,13 @@ LL ~ error: using `eprint!()` with a format string that ends in a single newline --> $DIR/eprint_with_newline.rs:47:5 | -LL | eprint!("/r/n"); //~ ERROR +LL | eprint!("//r/n"); | ^^^^^^^^^^^^^^^^ | help: use `eprintln!` instead | -LL - eprint!("/r/n"); //~ ERROR -LL + eprintln!("/r"); //~ ERROR +LL - eprint!("//r/n"); +LL + eprintln!("//r"); | error: aborting due to 9 previous errors diff --git a/tests/ui/eq_op.rs b/tests/ui/eq_op.rs index e73795502652..c34d0126ea6c 100644 --- a/tests/ui/eq_op.rs +++ b/tests/ui/eq_op.rs @@ -1,5 +1,8 @@ -// compile-flags: --test +<<<<<<< HEAD +======= +//@compile-flags: --test +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::eq_op)] #![allow(clippy::double_parens, clippy::identity_op, clippy::nonminimal_bool)] #![allow(clippy::suspicious_xor_used_as_pow)] @@ -12,6 +15,8 @@ fn main() { let _ = false != false; let _ = 1.5 < 1.5; let _ = 1u64 >= 1u64; + let x = f32::NAN; + let _ = x != x; // casts, methods, parentheses let _ = (1u32 as u64) & (1u32 as u64); diff --git a/tests/ui/eq_op.stderr b/tests/ui/eq_op.stderr index d365ab27edc2..c7fa253bdca2 100644 --- a/tests/ui/eq_op.stderr +++ b/tests/ui/eq_op.stderr @@ -1,5 +1,5 @@ error: equal expressions as operands to `==` - --> $DIR/eq_op.rs:9:13 + --> $DIR/eq_op.rs:7:13 | LL | let _ = 1 == 1; | ^^^^^^ @@ -7,29 +7,37 @@ LL | let _ = 1 == 1; = note: `-D clippy::eq-op` implied by `-D warnings` error: equal expressions as operands to `==` - --> $DIR/eq_op.rs:10:13 + --> $DIR/eq_op.rs:8:13 | LL | let _ = "no" == "no"; | ^^^^^^^^^^^^ error: equal expressions as operands to `!=` - --> $DIR/eq_op.rs:12:13 + --> $DIR/eq_op.rs:10:13 | LL | let _ = false != false; | ^^^^^^^^^^^^^^ error: equal expressions as operands to `<` - --> $DIR/eq_op.rs:13:13 + --> $DIR/eq_op.rs:11:13 | LL | let _ = 1.5 < 1.5; | ^^^^^^^^^ error: equal expressions as operands to `>=` - --> $DIR/eq_op.rs:14:13 + --> $DIR/eq_op.rs:12:13 | LL | let _ = 1u64 >= 1u64; | ^^^^^^^^^^^^ +error: equal expressions as operands to `!=` + --> $DIR/eq_op.rs:14:13 + | +LL | let _ = x != x; + | ^^^^^^ + | + = note: if you intended to check if the operand is NaN, use `.is_nan()` instead + error: equal expressions as operands to `&` --> $DIR/eq_op.rs:17:13 | @@ -168,5 +176,5 @@ error: equal expressions as operands to `==` LL | (n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 28 previous errors +error: aborting due to 29 previous errors diff --git a/tests/ui/eq_op_macros.rs b/tests/ui/eq_op_macros.rs index 6b5b31a1a2ef..482406772289 100644 --- a/tests/ui/eq_op_macros.rs +++ b/tests/ui/eq_op_macros.rs @@ -1,4 +1,5 @@ #![warn(clippy::eq_op)] +#![allow(clippy::useless_vec)] // lint also in macro definition macro_rules! assert_in_macro_def { diff --git a/tests/ui/eq_op_macros.stderr b/tests/ui/eq_op_macros.stderr index cd9f1826e59b..cb9b0c01862b 100644 --- a/tests/ui/eq_op_macros.stderr +++ b/tests/ui/eq_op_macros.stderr @@ -1,5 +1,5 @@ error: identical args used in this `assert_eq!` macro call - --> $DIR/eq_op_macros.rs:7:20 + --> $DIR/eq_op_macros.rs:8:20 | LL | assert_eq!(a, a); | ^^^^ @@ -11,7 +11,7 @@ LL | assert_in_macro_def!(); = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info) error: identical args used in this `assert_ne!` macro call - --> $DIR/eq_op_macros.rs:8:20 + --> $DIR/eq_op_macros.rs:9:20 | LL | assert_ne!(a, a); | ^^^^ @@ -22,7 +22,7 @@ LL | assert_in_macro_def!(); = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info) error: identical args used in this `debug_assert_eq!` macro call - --> $DIR/eq_op_macros.rs:9:26 + --> $DIR/eq_op_macros.rs:10:26 | LL | debug_assert_eq!(a, a); | ^^^^ @@ -33,7 +33,7 @@ LL | assert_in_macro_def!(); = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info) error: identical args used in this `debug_assert_ne!` macro call - --> $DIR/eq_op_macros.rs:10:26 + --> $DIR/eq_op_macros.rs:11:26 | LL | debug_assert_ne!(a, a); | ^^^^ @@ -44,49 +44,49 @@ LL | assert_in_macro_def!(); = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info) error: identical args used in this `assert_eq!` macro call - --> $DIR/eq_op_macros.rs:22:16 + --> $DIR/eq_op_macros.rs:23:16 | LL | assert_eq!(a, a); | ^^^^ error: identical args used in this `assert_eq!` macro call - --> $DIR/eq_op_macros.rs:23:16 + --> $DIR/eq_op_macros.rs:24:16 | LL | assert_eq!(a + 1, a + 1); | ^^^^^^^^^^^^ error: identical args used in this `assert_ne!` macro call - --> $DIR/eq_op_macros.rs:30:16 + --> $DIR/eq_op_macros.rs:31:16 | LL | assert_ne!(a, a); | ^^^^ error: identical args used in this `assert_ne!` macro call - --> $DIR/eq_op_macros.rs:31:16 + --> $DIR/eq_op_macros.rs:32:16 | LL | assert_ne!(a + 1, a + 1); | ^^^^^^^^^^^^ error: identical args used in this `debug_assert_eq!` macro call - --> $DIR/eq_op_macros.rs:38:22 + --> $DIR/eq_op_macros.rs:39:22 | LL | debug_assert_eq!(a, a); | ^^^^ error: identical args used in this `debug_assert_eq!` macro call - --> $DIR/eq_op_macros.rs:39:22 + --> $DIR/eq_op_macros.rs:40:22 | LL | debug_assert_eq!(a + 1, a + 1); | ^^^^^^^^^^^^ error: identical args used in this `debug_assert_ne!` macro call - --> $DIR/eq_op_macros.rs:46:22 + --> $DIR/eq_op_macros.rs:47:22 | LL | debug_assert_ne!(a, a); | ^^^^ error: identical args used in this `debug_assert_ne!` macro call - --> $DIR/eq_op_macros.rs:47:22 + --> $DIR/eq_op_macros.rs:48:22 | LL | debug_assert_ne!(a + 1, a + 1); | ^^^^^^^^^^^^ diff --git a/tests/ui/equatable_if_let.fixed b/tests/ui/equatable_if_let.fixed index 007702ab550b..79365dfd6b65 100644 --- a/tests/ui/equatable_if_let.fixed +++ b/tests/ui/equatable_if_let.fixed @@ -1,7 +1,16 @@ -// run-rustfix -// aux-build:proc_macros.rs - -#![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) + +#![allow( + unused_variables, + dead_code, + clippy::derive_partial_eq_without_eq, + clippy::needless_if +)] #![warn(clippy::equatable_if_let)] extern crate proc_macros; diff --git a/tests/ui/equatable_if_let.rs b/tests/ui/equatable_if_let.rs index 3bda7977645b..898748fbd399 100644 --- a/tests/ui/equatable_if_let.rs +++ b/tests/ui/equatable_if_let.rs @@ -1,7 +1,16 @@ -// run-rustfix -// aux-build:proc_macros.rs - -#![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) + +#![allow( + unused_variables, + dead_code, + clippy::derive_partial_eq_without_eq, + clippy::needless_if +)] #![warn(clippy::equatable_if_let)] extern crate proc_macros; diff --git a/tests/ui/equatable_if_let.stderr b/tests/ui/equatable_if_let.stderr index a72d87bb7ba9..649495dded7d 100644 --- a/tests/ui/equatable_if_let.stderr +++ b/tests/ui/equatable_if_let.stderr @@ -1,5 +1,5 @@ error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:60:8 + --> $DIR/equatable_if_let.rs:65:8 | LL | if let 2 = a {} | ^^^^^^^^^ help: try: `a == 2` @@ -7,79 +7,79 @@ LL | if let 2 = a {} = note: `-D clippy::equatable-if-let` implied by `-D warnings` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:61:8 + --> $DIR/equatable_if_let.rs:66:8 | LL | if let Ordering::Greater = a.cmp(&b) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:62:8 + --> $DIR/equatable_if_let.rs:67:8 | LL | if let Some(2) = c {} | ^^^^^^^^^^^^^^^ help: try: `c == Some(2)` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:63:8 + --> $DIR/equatable_if_let.rs:68:8 | LL | if let Struct { a: 2, b: false } = d {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d == (Struct { a: 2, b: false })` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:64:8 + --> $DIR/equatable_if_let.rs:69:8 | LL | if let Enum::TupleVariant(32, 64) = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::TupleVariant(32, 64)` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:65:8 + --> $DIR/equatable_if_let.rs:70:8 | LL | if let Enum::RecordVariant { a: 64, b: 32 } = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == (Enum::RecordVariant { a: 64, b: 32 })` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:66:8 + --> $DIR/equatable_if_let.rs:71:8 | LL | if let Enum::UnitVariant = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:67:8 + --> $DIR/equatable_if_let.rs:72:8 | LL | if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false })` error: this pattern matching can be expressed using `matches!` - --> $DIR/equatable_if_let.rs:76:8 + --> $DIR/equatable_if_let.rs:81:8 | LL | if let NotPartialEq::A = f {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(f, NotPartialEq::A)` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:77:8 + --> $DIR/equatable_if_let.rs:82:8 | LL | if let NotStructuralEq::A = g {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A` error: this pattern matching can be expressed using `matches!` - --> $DIR/equatable_if_let.rs:78:8 + --> $DIR/equatable_if_let.rs:83:8 | LL | if let Some(NotPartialEq::A) = Some(f) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(f), Some(NotPartialEq::A))` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:79:8 + --> $DIR/equatable_if_let.rs:84:8 | LL | if let Some(NotStructuralEq::A) = Some(g) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)` error: this pattern matching can be expressed using `matches!` - --> $DIR/equatable_if_let.rs:80:8 + --> $DIR/equatable_if_let.rs:85:8 | LL | if let NoPartialEqStruct { a: 2, b: false } = h {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(h, NoPartialEqStruct { a: 2, b: false })` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:82:8 + --> $DIR/equatable_if_let.rs:87:8 | LL | if let inline!("abc") = "abc" { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"abc" == inline!("abc")` diff --git a/tests/ui/err_expect.fixed b/tests/ui/err_expect.fixed index b63cbd8a8e6b..46e2816da522 100644 --- a/tests/ui/err_expect.fixed +++ b/tests/ui/err_expect.fixed @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix -#![allow(unused)] +#![allow(unused, clippy::unnecessary_literal_unwrap)] struct MyTypeNonDebug; diff --git a/tests/ui/err_expect.rs b/tests/ui/err_expect.rs index c081a745fb40..b9446034d50a 100644 --- a/tests/ui/err_expect.rs +++ b/tests/ui/err_expect.rs @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix -#![allow(unused)] +#![allow(unused, clippy::unnecessary_literal_unwrap)] struct MyTypeNonDebug; diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed index dc129591eac4..fb53269f32ae 100644 --- a/tests/ui/eta.fixed +++ b/tests/ui/eta.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)] #![allow(unused)] #![allow( @@ -7,7 +7,8 @@ clippy::no_effect, clippy::option_map_unit_fn, clippy::redundant_closure_call, - clippy::uninlined_format_args + clippy::uninlined_format_args, + clippy::useless_vec )] use std::path::{Path, PathBuf}; @@ -46,6 +47,20 @@ fn main() { // issue #7224 let _: Option> = Some(0).map(|_| vec![]); + + // issue #10684 + fn test(x: impl Fn(usize, usize) -> T) -> T { + x(1, 2) + } +<<<<<<< HEAD +<<<<<<< HEAD + test(|start, end| start..=end); +======= + test(core::ops::RangeInclusive::new); +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + test(|start, end| start..=end); +>>>>>>> 9ff34acf2 (actually don't lint for inclusive range) } trait TestTrait { diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index 025fd6a0b7af..b2af4bf09537 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)] #![allow(unused)] #![allow( @@ -7,7 +7,8 @@ clippy::no_effect, clippy::option_map_unit_fn, clippy::redundant_closure_call, - clippy::uninlined_format_args + clippy::uninlined_format_args, + clippy::useless_vec )] use std::path::{Path, PathBuf}; @@ -46,6 +47,12 @@ fn main() { // issue #7224 let _: Option> = Some(0).map(|_| vec![]); + + // issue #10684 + fn test(x: impl Fn(usize, usize) -> T) -> T { + x(1, 2) + } + test(|start, end| start..=end); } trait TestTrait { diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr index a521fb868607..baaca06b41a8 100644 --- a/tests/ui/eta.stderr +++ b/tests/ui/eta.stderr @@ -1,5 +1,5 @@ error: redundant closure - --> $DIR/eta.rs:28:27 + --> $DIR/eta.rs:29:27 | LL | let a = Some(1u8).map(|a| foo(a)); | ^^^^^^^^^^ help: replace the closure with the function itself: `foo` @@ -7,31 +7,48 @@ LL | let a = Some(1u8).map(|a| foo(a)); = note: `-D clippy::redundant-closure` implied by `-D warnings` error: redundant closure - --> $DIR/eta.rs:32:40 + --> $DIR/eta.rs:33:40 | LL | let _: Option> = true.then(|| vec![]); // special case vec! | ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new` error: redundant closure - --> $DIR/eta.rs:33:35 + --> $DIR/eta.rs:34:35 | LL | let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted? | ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2` error: redundant closure - --> $DIR/eta.rs:34:26 + --> $DIR/eta.rs:35:26 | LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted | ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below` error: redundant closure - --> $DIR/eta.rs:41:27 + --> $DIR/eta.rs:42:27 | LL | let e = Some(1u8).map(|a| generic(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic` error: redundant closure - --> $DIR/eta.rs:87:51 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:94:51 +======= + --> $DIR/eta.rs:54:10 + | +LL | test(|start, end| start..=end); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `core::ops::RangeInclusive::new` + +error: redundant closure +======= +>>>>>>> 9ff34acf2 (actually don't lint for inclusive range) + --> $DIR/eta.rs:93:51 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:94:51 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); | ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo` @@ -39,121 +56,281 @@ LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); = note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings` error: redundant closure - --> $DIR/eta.rs:88:51 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:95:51 +======= + --> $DIR/eta.rs:94:51 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:95:51 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo()); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo` error: redundant closure - --> $DIR/eta.rs:90:42 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:97:42 +======= + --> $DIR/eta.rs:96:42 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:97:42 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear()); | ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear` error: redundant closure - --> $DIR/eta.rs:94:29 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:101:29 +======= + --> $DIR/eta.rs:100:29 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:101:29 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | let e = Some("str").map(|s| s.to_string()); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string` error: redundant closure - --> $DIR/eta.rs:95:27 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:102:27 +======= + --> $DIR/eta.rs:101:27 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:102:27 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | let e = Some('a').map(|s| s.to_uppercase()); | ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase` error: redundant closure - --> $DIR/eta.rs:97:65 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:104:65 +======= + --> $DIR/eta.rs:103:65 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:104:65 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase` error: redundant closure - --> $DIR/eta.rs:160:22 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:167:22 +======= + --> $DIR/eta.rs:166:22 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:167:22 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | requires_fn_once(|| x()); | ^^^^^^ help: replace the closure with the function itself: `x` error: redundant closure - --> $DIR/eta.rs:167:27 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:174:27 +======= + --> $DIR/eta.rs:173:27 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:174:27 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | let a = Some(1u8).map(|a| foo_ptr(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr` error: redundant closure - --> $DIR/eta.rs:172:27 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:179:27 +======= + --> $DIR/eta.rs:178:27 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:179:27 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | let a = Some(1u8).map(|a| closure(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure` error: redundant closure - --> $DIR/eta.rs:204:28 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:211:28 +======= + --> $DIR/eta.rs:210:28 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:211:28 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | x.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` error: redundant closure - --> $DIR/eta.rs:205:28 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:212:28 +======= + --> $DIR/eta.rs:211:28 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:212:28 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | y.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` error: redundant closure - --> $DIR/eta.rs:206:28 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:213:28 +======= + --> $DIR/eta.rs:212:28 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:213:28 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | z.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res` error: redundant closure - --> $DIR/eta.rs:213:21 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:220:21 +======= + --> $DIR/eta.rs:219:21 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:220:21 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | Some(1).map(|n| closure(n)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure` error: redundant closure - --> $DIR/eta.rs:217:21 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:224:21 +======= + --> $DIR/eta.rs:223:21 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:224:21 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | Some(1).map(|n| in_loop(n)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop` error: redundant closure - --> $DIR/eta.rs:310:18 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:317:18 +======= + --> $DIR/eta.rs:316:18 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:317:18 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | takes_fn_mut(|| f()); | ^^^^^^ help: replace the closure with the function itself: `&mut f` error: redundant closure - --> $DIR/eta.rs:313:19 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:320:19 +======= + --> $DIR/eta.rs:319:19 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:320:19 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | takes_fn_once(|| f()); | ^^^^^^ help: replace the closure with the function itself: `&mut f` error: redundant closure - --> $DIR/eta.rs:317:26 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:324:26 +======= + --> $DIR/eta.rs:323:26 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:324:26 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | move || takes_fn_mut(|| f_used_once()) | ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once` error: redundant closure - --> $DIR/eta.rs:329:19 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:336:19 +======= + --> $DIR/eta.rs:335:19 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:336:19 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | array_opt.map(|a| a.as_slice()); | ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice` error: redundant closure - --> $DIR/eta.rs:332:19 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:339:19 +======= + --> $DIR/eta.rs:338:19 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:339:19 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | slice_opt.map(|s| s.len()); | ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len` error: redundant closure - --> $DIR/eta.rs:335:17 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:342:17 +======= + --> $DIR/eta.rs:341:17 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:342:17 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | ptr_opt.map(|p| p.is_null()); | ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null` error: redundant closure - --> $DIR/eta.rs:339:17 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/eta.rs:346:17 +======= + --> $DIR/eta.rs:345:17 +>>>>>>> 2c7cf2cfa (handle RangeInclusive function desugar) +======= + --> $DIR/eta.rs:346:17 +>>>>>>> 50ba45998 (add- and fix existing tests) | LL | dyn_opt.map(|d| d.method_on_dyn()); | ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `::method_on_dyn` diff --git a/tests/ui/excessive_precision.fixed b/tests/ui/excessive_precision.fixed index b74bda182be9..7318f9b6de2e 100644 --- a/tests/ui/excessive_precision.fixed +++ b/tests/ui/excessive_precision.fixed @@ -1,6 +1,22 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::excessive_precision)] -#![allow(dead_code, unused_variables, clippy::print_literal)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a89903492 (Don't lint `excessive_precision` on inf) +#![allow( + dead_code, + overflowing_literals, + unused_variables, + clippy::print_literal, + clippy::useless_vec +)] +<<<<<<< HEAD +======= +#![allow(dead_code, unused_variables, clippy::print_literal, clippy::useless_vec)] +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +>>>>>>> a89903492 (Don't lint `excessive_precision` on inf) fn main() { // Consts @@ -66,4 +82,11 @@ fn main() { // issue #7745 let _ = 0_f64; + + // issue #9910 + const INF1: f32 = 1.0e+33f32; + const INF2: f64 = 1.0e+3300f64; + const NEG_INF1: f32 = -1.0e+33f32; + const NEG_INF2: f64 = -1.0e+3300f64; + const NEG_INF3: f32 = -3.40282357e+38_f32; } diff --git a/tests/ui/excessive_precision.rs b/tests/ui/excessive_precision.rs index 6e84a71f24cb..443e5e695682 100644 --- a/tests/ui/excessive_precision.rs +++ b/tests/ui/excessive_precision.rs @@ -1,6 +1,22 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::excessive_precision)] -#![allow(dead_code, unused_variables, clippy::print_literal)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a89903492 (Don't lint `excessive_precision` on inf) +#![allow( + dead_code, + overflowing_literals, + unused_variables, + clippy::print_literal, + clippy::useless_vec +)] +<<<<<<< HEAD +======= +#![allow(dead_code, unused_variables, clippy::print_literal, clippy::useless_vec)] +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +>>>>>>> a89903492 (Don't lint `excessive_precision` on inf) fn main() { // Consts @@ -66,4 +82,11 @@ fn main() { // issue #7745 let _ = 1.000_000_000_000_001e-324_f64; + + // issue #9910 + const INF1: f32 = 1.0e+33f32; + const INF2: f64 = 1.0e+3300f64; + const NEG_INF1: f32 = -1.0e+33f32; + const NEG_INF2: f64 = -1.0e+3300f64; + const NEG_INF3: f32 = -3.40282357e+38_f32; } diff --git a/tests/ui/excessive_precision.stderr b/tests/ui/excessive_precision.stderr index 42d9d4de193c..348ad183d7d7 100644 --- a/tests/ui/excessive_precision.stderr +++ b/tests/ui/excessive_precision.stderr @@ -1,5 +1,5 @@ error: float has excessive precision - --> $DIR/excessive_precision.rs:15:26 + --> $DIR/excessive_precision.rs:21:26 | LL | const BAD32_1: f32 = 0.123_456_789_f32; | ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79_f32` @@ -7,85 +7,85 @@ LL | const BAD32_1: f32 = 0.123_456_789_f32; = note: `-D clippy::excessive-precision` implied by `-D warnings` error: float has excessive precision - --> $DIR/excessive_precision.rs:16:26 + --> $DIR/excessive_precision.rs:22:26 | LL | const BAD32_2: f32 = 0.123_456_789; | ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79` error: float has excessive precision - --> $DIR/excessive_precision.rs:17:26 + --> $DIR/excessive_precision.rs:23:26 | LL | const BAD32_3: f32 = 0.100_000_000_000_1; | ^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.1` error: float has excessive precision - --> $DIR/excessive_precision.rs:18:29 + --> $DIR/excessive_precision.rs:24:29 | LL | const BAD32_EDGE: f32 = 1.000_000_9; | ^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.000_001` error: float has excessive precision - --> $DIR/excessive_precision.rs:22:26 + --> $DIR/excessive_precision.rs:28:26 | LL | const BAD64_3: f64 = 0.100_000_000_000_000_000_1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.1` error: float has excessive precision - --> $DIR/excessive_precision.rs:25:22 + --> $DIR/excessive_precision.rs:31:22 | LL | println!("{:?}", 8.888_888_888_888_888_888_888); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `8.888_888_888_888_89` error: float has excessive precision - --> $DIR/excessive_precision.rs:36:22 + --> $DIR/excessive_precision.rs:42:22 | LL | let bad32: f32 = 1.123_456_789; | ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8` error: float has excessive precision - --> $DIR/excessive_precision.rs:37:26 + --> $DIR/excessive_precision.rs:43:26 | LL | let bad32_suf: f32 = 1.123_456_789_f32; | ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8_f32` error: float has excessive precision - --> $DIR/excessive_precision.rs:38:21 + --> $DIR/excessive_precision.rs:44:21 | LL | let bad32_inf = 1.123_456_789_f32; | ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8_f32` error: float has excessive precision - --> $DIR/excessive_precision.rs:48:36 + --> $DIR/excessive_precision.rs:54:36 | LL | let bad_vec32: Vec = vec![0.123_456_789]; | ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79` error: float has excessive precision - --> $DIR/excessive_precision.rs:49:36 + --> $DIR/excessive_precision.rs:55:36 | LL | let bad_vec64: Vec = vec![0.123_456_789_123_456_789]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_123_456_78` error: float has excessive precision - --> $DIR/excessive_precision.rs:53:24 + --> $DIR/excessive_precision.rs:59:24 | LL | let bad_e32: f32 = 1.123_456_788_888e-10; | ^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8e-10` error: float has excessive precision - --> $DIR/excessive_precision.rs:56:27 + --> $DIR/excessive_precision.rs:62:27 | LL | let bad_bige32: f32 = 1.123_456_788_888E-10; | ^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8E-10` error: float has excessive precision - --> $DIR/excessive_precision.rs:65:13 + --> $DIR/excessive_precision.rs:71:13 | LL | let _ = 2.225_073_858_507_201_1e-308_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `2.225_073_858_507_201e-308_f64` error: float has excessive precision - --> $DIR/excessive_precision.rs:68:13 + --> $DIR/excessive_precision.rs:74:13 | LL | let _ = 1.000_000_000_000_001e-324_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0_f64` diff --git a/tests/ui/exhaustive_items.fixed b/tests/ui/exhaustive_items.fixed index c209f5b4b727..6c7b1cab6f20 100644 --- a/tests/ui/exhaustive_items.fixed +++ b/tests/ui/exhaustive_items.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)] #![allow(unused)] diff --git a/tests/ui/exhaustive_items.rs b/tests/ui/exhaustive_items.rs index 6f59dbf2da59..d205bac2d2ab 100644 --- a/tests/ui/exhaustive_items.rs +++ b/tests/ui/exhaustive_items.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)] #![allow(unused)] diff --git a/tests/ui/expect.rs b/tests/ui/expect.rs index d742595e14d4..1588579bb0f2 100644 --- a/tests/ui/expect.rs +++ b/tests/ui/expect.rs @@ -1,4 +1,5 @@ #![warn(clippy::expect_used)] +#![allow(clippy::unnecessary_literal_unwrap)] fn expect_option() { let opt = Some(0); diff --git a/tests/ui/expect.stderr b/tests/ui/expect.stderr index c08e0dbbf744..be340340d477 100644 --- a/tests/ui/expect.stderr +++ b/tests/ui/expect.stderr @@ -1,5 +1,5 @@ error: used `expect()` on an `Option` value - --> $DIR/expect.rs:5:13 + --> $DIR/expect.rs:6:13 | LL | let _ = opt.expect(""); | ^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let _ = opt.expect(""); = note: `-D clippy::expect-used` implied by `-D warnings` error: used `expect()` on a `Result` value - --> $DIR/expect.rs:10:13 + --> $DIR/expect.rs:11:13 | LL | let _ = res.expect(""); | ^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | let _ = res.expect(""); = help: if this value is an `Err`, it will panic error: used `expect_err()` on a `Result` value - --> $DIR/expect.rs:11:13 + --> $DIR/expect.rs:12:13 | LL | let _ = res.expect_err(""); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/expect_fun_call.fixed b/tests/ui/expect_fun_call.fixed index 15172ae345c2..73c6c97de84b 100644 --- a/tests/ui/expect_fun_call.fixed +++ b/tests/ui/expect_fun_call.fixed @@ -1,6 +1,10 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::expect_fun_call)] -#![allow(clippy::to_string_in_format_args, clippy::uninlined_format_args)] +#![allow( + clippy::to_string_in_format_args, + clippy::uninlined_format_args, + clippy::unnecessary_literal_unwrap +)] /// Checks implementation of the `EXPECT_FUN_CALL` lint diff --git a/tests/ui/expect_fun_call.rs b/tests/ui/expect_fun_call.rs index 0f448d004174..a786138631c8 100644 --- a/tests/ui/expect_fun_call.rs +++ b/tests/ui/expect_fun_call.rs @@ -1,6 +1,10 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::expect_fun_call)] -#![allow(clippy::to_string_in_format_args, clippy::uninlined_format_args)] +#![allow( + clippy::to_string_in_format_args, + clippy::uninlined_format_args, + clippy::unnecessary_literal_unwrap +)] /// Checks implementation of the `EXPECT_FUN_CALL` lint diff --git a/tests/ui/expect_fun_call.stderr b/tests/ui/expect_fun_call.stderr index cb55e32aee02..a621f681d981 100644 --- a/tests/ui/expect_fun_call.stderr +++ b/tests/ui/expect_fun_call.stderr @@ -1,94 +1,94 @@ error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:34:26 + --> $DIR/expect_fun_call.rs:38:26 | LL | with_none_and_format.expect(&format!("Error {}: fake error", error_code)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))` | = note: `-D clippy::expect-fun-call` implied by `-D warnings` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:37:26 + --> $DIR/expect_fun_call.rs:41:26 | LL | with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:40:37 + --> $DIR/expect_fun_call.rs:44:37 | LL | with_none_and_format_with_macro.expect(format!("Error {}: fake error", one!()).as_str()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("Error {}: fake error", one!()))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", one!()))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:50:25 + --> $DIR/expect_fun_call.rs:54:25 | LL | with_err_and_format.expect(&format!("Error {}: fake error", error_code)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:53:25 + --> $DIR/expect_fun_call.rs:57:25 | LL | with_err_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:65:17 + --> $DIR/expect_fun_call.rs:69:17 | LL | Some("foo").expect(format!("{} {}", 1, 2).as_ref()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("{} {}", 1, 2))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{} {}", 1, 2))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:86:21 + --> $DIR/expect_fun_call.rs:90:21 | LL | Some("foo").expect(&get_string()); - | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_string()) })` + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:87:21 + --> $DIR/expect_fun_call.rs:91:21 | LL | Some("foo").expect(get_string().as_ref()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_string()) })` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:88:21 + --> $DIR/expect_fun_call.rs:92:21 | LL | Some("foo").expect(get_string().as_str()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_string()) })` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:90:21 + --> $DIR/expect_fun_call.rs:94:21 | LL | Some("foo").expect(get_static_str()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_static_str()) })` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_static_str()) })` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:91:21 + --> $DIR/expect_fun_call.rs:95:21 | LL | Some("foo").expect(get_non_static_str(&0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) })` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) })` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:95:16 + --> $DIR/expect_fun_call.rs:99:16 | LL | Some(true).expect(&format!("key {}, {}", 1, 2)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("key {}, {}", 1, 2))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("key {}, {}", 1, 2))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:101:17 + --> $DIR/expect_fun_call.rs:105:17 | LL | opt_ref.expect(&format!("{:?}", opt_ref)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("{:?}", opt_ref))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{:?}", opt_ref))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:105:20 + --> $DIR/expect_fun_call.rs:109:20 | LL | format_capture.expect(&format!("{error_code}")); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("{error_code}"))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}"))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:108:30 + --> $DIR/expect_fun_call.rs:112:30 | LL | format_capture_and_value.expect(&format!("{error_code}, {}", 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("{error_code}, {}", 1))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}, {}", 1))` error: aborting due to 15 previous errors diff --git a/tests/ui/expect_tool_lint_rfc_2383.rs b/tests/ui/expect_tool_lint_rfc_2383.rs index 018f875d60bf..7963bf0f3a6a 100644 --- a/tests/ui/expect_tool_lint_rfc_2383.rs +++ b/tests/ui/expect_tool_lint_rfc_2383.rs @@ -1,4 +1,3 @@ -// check-pass #![feature(lint_reasons)] //! This file tests the `#[expect]` attribute implementation for tool lints. The same //! file is used to test clippy and rustdoc. Any changes to this file should be synced @@ -12,6 +11,7 @@ //! This test can't cover every lint from Clippy, rustdoc and potentially other //! tools that will be developed. This therefore only tests a small subset of lints #![expect(rustdoc::missing_crate_level_docs)] +#![allow(clippy::needless_if)] mod rustc_ok { //! See diff --git a/tests/ui/explicit_auto_deref.fixed b/tests/ui/explicit_auto_deref.fixed index 5d40c850424f..71a5ed96d5c4 100644 --- a/tests/ui/explicit_auto_deref.fixed +++ b/tests/ui/explicit_auto_deref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(closure_lifetime_binder)] #![warn(clippy::explicit_auto_deref)] diff --git a/tests/ui/explicit_auto_deref.rs b/tests/ui/explicit_auto_deref.rs index 79e03f4d76c1..9d0cafa150f6 100644 --- a/tests/ui/explicit_auto_deref.rs +++ b/tests/ui/explicit_auto_deref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(closure_lifetime_binder)] #![warn(clippy::explicit_auto_deref)] diff --git a/tests/ui/explicit_auto_deref.stderr b/tests/ui/explicit_auto_deref.stderr index 91863abcc5d2..afc311e3f7cd 100644 --- a/tests/ui/explicit_auto_deref.stderr +++ b/tests/ui/explicit_auto_deref.stderr @@ -2,7 +2,7 @@ error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:70:19 | LL | let _: &str = &*s; - | ^^^ help: try this: `&s` + | ^^^ help: try: `&s` | = note: `-D clippy::explicit-auto-deref` implied by `-D warnings` @@ -10,229 +10,229 @@ error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:71:19 | LL | let _: &str = &*{ String::new() }; - | ^^^^^^^^^^^^^^^^^^^ help: try this: `&{ String::new() }` + | ^^^^^^^^^^^^^^^^^^^ help: try: `&{ String::new() }` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:72:19 | LL | let _: &str = &mut *{ String::new() }; - | ^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut { String::new() }` + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut { String::new() }` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:76:11 | LL | f_str(&*s); - | ^^^ help: try this: `&s` + | ^^^ help: try: `&s` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:80:13 | LL | f_str_t(&*s, &*s); // Don't lint second param. - | ^^^ help: try this: `&s` + | ^^^ help: try: `&s` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:83:24 | LL | let _: &Box = &**b; - | ^^^^ help: try this: `&b` + | ^^^^ help: try: `&b` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:89:7 | LL | c(&*s); - | ^^^ help: try this: `&s` + | ^^^ help: try: `&s` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:95:9 | LL | &**x - | ^^^^ help: try this: `x` + | ^^^^ help: try: `x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:99:11 | LL | { &**x } - | ^^^^ help: try this: `x` + | ^^^^ help: try: `x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:103:9 | LL | &**{ x } - | ^^^^^^^^ help: try this: `{ x }` + | ^^^^^^^^ help: try: `{ x }` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:107:9 | LL | &***x - | ^^^^^ help: try this: `x` + | ^^^^^ help: try: `x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:124:12 | LL | f1(&*x); - | ^^^ help: try this: `&x` + | ^^^ help: try: `&x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:125:12 | LL | f2(&*x); - | ^^^ help: try this: `&x` + | ^^^ help: try: `&x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:126:12 | LL | f3(&*x); - | ^^^ help: try this: `&x` + | ^^^ help: try: `&x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:127:27 | LL | f4.callable_str()(&*x); - | ^^^ help: try this: `&x` + | ^^^ help: try: `&x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:128:12 | LL | f5(&*x); - | ^^^ help: try this: `&x` + | ^^^ help: try: `&x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:129:12 | LL | f6(&*x); - | ^^^ help: try this: `&x` + | ^^^ help: try: `&x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:130:27 | LL | f7.callable_str()(&*x); - | ^^^ help: try this: `&x` + | ^^^ help: try: `&x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:131:25 | LL | f8.callable_t()(&*x); - | ^^^ help: try this: `&x` + | ^^^ help: try: `&x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:132:12 | LL | f9(&*x); - | ^^^ help: try this: `&x` + | ^^^ help: try: `&x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:133:13 | LL | f10(&*x); - | ^^^ help: try this: `&x` + | ^^^ help: try: `&x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:134:26 | LL | f11.callable_t()(&*x); - | ^^^ help: try this: `&x` + | ^^^ help: try: `&x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:138:16 | LL | let _ = S1(&*s); - | ^^^ help: try this: `&s` + | ^^^ help: try: `&s` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:143:21 | LL | let _ = S2 { s: &*s }; - | ^^^ help: try this: `&s` + | ^^^ help: try: `&s` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:159:30 | LL | let _ = Self::S1(&**s); - | ^^^^ help: try this: `s` + | ^^^^ help: try: `s` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:160:35 | LL | let _ = Self::S2 { s: &**s }; - | ^^^^ help: try this: `s` + | ^^^^ help: try: `s` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:163:20 | LL | let _ = E1::S1(&*s); - | ^^^ help: try this: `&s` + | ^^^ help: try: `&s` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:164:25 | LL | let _ = E1::S2 { s: &*s }; - | ^^^ help: try this: `&s` + | ^^^ help: try: `&s` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:182:13 | LL | let _ = (*b).foo; - | ^^^^ help: try this: `b` + | ^^^^ help: try: `b` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:183:13 | LL | let _ = (**b).foo; - | ^^^^^ help: try this: `b` + | ^^^^^ help: try: `b` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:198:19 | LL | let _ = f_str(*ref_str); - | ^^^^^^^^ help: try this: `ref_str` + | ^^^^^^^^ help: try: `ref_str` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:200:19 | LL | let _ = f_str(**ref_ref_str); - | ^^^^^^^^^^^^^ help: try this: `ref_ref_str` + | ^^^^^^^^^^^^^ help: try: `ref_ref_str` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:210:13 | LL | f_str(&&*ref_str); // `needless_borrow` will suggest removing both references - | ^^^^^^^^ help: try this: `ref_str` + | ^^^^^^^^ help: try: `ref_str` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:211:12 | LL | f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference - | ^^^^^^^^^^ help: try this: `ref_str` + | ^^^^^^^^^^ help: try: `ref_str` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:220:41 | LL | let _ = || -> &'static str { return *s }; - | ^^ help: try this: `s` + | ^^ help: try: `s` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:239:9 | LL | &**x - | ^^^^ help: try this: `x` + | ^^^^ help: try: `x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:262:8 | LL | c1(*x); - | ^^ help: try this: `x` + | ^^ help: try: `x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:265:20 | LL | return *x; - | ^^ help: try this: `x` + | ^^ help: try: `x` error: deref which would be done by auto-deref --> $DIR/explicit_auto_deref.rs:267:9 | LL | *x - | ^^ help: try this: `x` + | ^^ help: try: `x` error: aborting due to 39 previous errors diff --git a/tests/ui/explicit_counter_loop.rs b/tests/ui/explicit_counter_loop.rs index 46565a97f005..e02b8f62b3dd 100644 --- a/tests/ui/explicit_counter_loop.rs +++ b/tests/ui/explicit_counter_loop.rs @@ -1,5 +1,5 @@ #![warn(clippy::explicit_counter_loop)] -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::uninlined_format_args, clippy::useless_vec)] fn main() { let mut vec = vec![1, 2, 3, 4]; @@ -23,6 +23,54 @@ fn main() { for _v in vec { _index += 1; } + + let vec = [1, 2, 3, 4]; + // Potential false positives + let mut _index = 0; + _index = 1; + for _v in &vec { + _index += 1 + } + + let mut _index = 0; + _index += 1; + for _v in &vec { + _index += 1 + } + + let mut _index = 0; + for _v in &vec { + _index = 1; + _index += 1 + } + + let mut _index = 0; + for _v in &vec { + let mut _index = 0; + _index += 1 + } + + let mut _index = 0; + for _v in &vec { + _index += 1; + _index = 0; + } + + let mut _index = 0; + if true { + _index = 1 + }; + for _v in &vec { + _index += 1 + } + + let mut _index = 1; + if false { + _index = 0 + }; + for _v in &vec { + _index += 1 + } } mod issue_1219 { diff --git a/tests/ui/explicit_counter_loop.stderr b/tests/ui/explicit_counter_loop.stderr index d3f3c626bbdf..0677e4d78c8b 100644 --- a/tests/ui/explicit_counter_loop.stderr +++ b/tests/ui/explicit_counter_loop.stderr @@ -25,31 +25,31 @@ LL | for _v in vec { | ^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.into_iter().enumerate()` error: the variable `count` is used as a loop counter - --> $DIR/explicit_counter_loop.rs:62:9 + --> $DIR/explicit_counter_loop.rs:110:9 | LL | for ch in text.chars() { | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()` error: the variable `count` is used as a loop counter - --> $DIR/explicit_counter_loop.rs:73:9 + --> $DIR/explicit_counter_loop.rs:121:9 | LL | for ch in text.chars() { | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()` error: the variable `count` is used as a loop counter - --> $DIR/explicit_counter_loop.rs:131:9 + --> $DIR/explicit_counter_loop.rs:179:9 | LL | for _i in 3..10 { | ^^^^^^^^^^^^^^^ help: consider using: `for (count, _i) in (3..10).enumerate()` error: the variable `idx_usize` is used as a loop counter - --> $DIR/explicit_counter_loop.rs:171:9 + --> $DIR/explicit_counter_loop.rs:219:9 | LL | for _item in slice { | ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_usize, _item) in slice.iter().enumerate()` error: the variable `idx_u32` is used as a loop counter - --> $DIR/explicit_counter_loop.rs:183:9 + --> $DIR/explicit_counter_loop.rs:231:9 | LL | for _item in slice { | ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_u32, _item) in (0_u32..).zip(slice.iter())` diff --git a/tests/ui/explicit_deref_methods.fixed b/tests/ui/explicit_deref_methods.fixed index 6d32bbece1e5..6a1d0c3be3c0 100644 --- a/tests/ui/explicit_deref_methods.fixed +++ b/tests/ui/explicit_deref_methods.fixed @@ -1,12 +1,23 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::explicit_deref_methods)] -#![allow(unused_variables)] +#![allow(unused_variables, unused_must_use)] #![allow( clippy::borrow_deref_ref, - clippy::clone_double_ref, + suspicious_double_ref_op, clippy::explicit_auto_deref, clippy::needless_borrow, + clippy::no_effect, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::uninlined_format_args, + clippy::unnecessary_literal_unwrap +======= clippy::uninlined_format_args +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + clippy::uninlined_format_args, + clippy::unnecessary_literal_unwrap +>>>>>>> bfd5abad4 (Fix all the other tests) )] use std::ops::{Deref, DerefMut}; @@ -28,6 +39,22 @@ impl Deref for CustomVec { } } +struct Aaa; + +impl Deref for Aaa { + type Target = (); + + fn deref(&self) -> &Self::Target { + todo!(); + } +} + +impl DerefMut for Aaa { + fn deref_mut(&mut self) -> &mut Self::Target { + todo!(); + } +} + fn main() { let a: &mut String = &mut String::from("foo"); @@ -58,6 +85,39 @@ fn main() { let opt_a = Some(a.clone()); let b = &*opt_a.unwrap(); +<<<<<<< HEAD +<<<<<<< HEAD + // make sure `Aaa::deref` instead of `aaa.deref()` is not linted, as well as fully qualified + // syntax + + Aaa::deref(&Aaa); + Aaa::deref_mut(&mut Aaa); + ::deref(&Aaa); + ::deref_mut(&mut Aaa); + let mut aaa = Aaa; + Aaa::deref(&aaa); + Aaa::deref_mut(&mut aaa); +======= + // make sure `Aaa::deref` instead of `aaa.deref()` works as well as fully qualified syntax +======= + // make sure `Aaa::deref` instead of `aaa.deref()` is not linted, as well as fully qualified + // syntax +>>>>>>> eed466281 (ignore `Foo::deref` altogether) + + Aaa::deref(&Aaa); + Aaa::deref_mut(&mut Aaa); + ::deref(&Aaa); + ::deref_mut(&mut Aaa); + let mut aaa = Aaa; +<<<<<<< HEAD + &*aaa; + &mut *aaa; +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + Aaa::deref(&aaa); + Aaa::deref_mut(&mut aaa); +>>>>>>> eed466281 (ignore `Foo::deref` altogether) + // following should not require linting let cv = CustomVec(vec![0, 42]); diff --git a/tests/ui/explicit_deref_methods.rs b/tests/ui/explicit_deref_methods.rs index 779909e42380..a75668e1ec47 100644 --- a/tests/ui/explicit_deref_methods.rs +++ b/tests/ui/explicit_deref_methods.rs @@ -1,12 +1,23 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::explicit_deref_methods)] -#![allow(unused_variables)] +#![allow(unused_variables, unused_must_use)] #![allow( clippy::borrow_deref_ref, - clippy::clone_double_ref, + suspicious_double_ref_op, clippy::explicit_auto_deref, clippy::needless_borrow, + clippy::no_effect, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::uninlined_format_args, + clippy::unnecessary_literal_unwrap +======= clippy::uninlined_format_args +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + clippy::uninlined_format_args, + clippy::unnecessary_literal_unwrap +>>>>>>> bfd5abad4 (Fix all the other tests) )] use std::ops::{Deref, DerefMut}; @@ -28,6 +39,22 @@ impl Deref for CustomVec { } } +struct Aaa; + +impl Deref for Aaa { + type Target = (); + + fn deref(&self) -> &Self::Target { + todo!(); + } +} + +impl DerefMut for Aaa { + fn deref_mut(&mut self) -> &mut Self::Target { + todo!(); + } +} + fn main() { let a: &mut String = &mut String::from("foo"); @@ -58,6 +85,26 @@ fn main() { let opt_a = Some(a.clone()); let b = opt_a.unwrap().deref(); +<<<<<<< HEAD +<<<<<<< HEAD + // make sure `Aaa::deref` instead of `aaa.deref()` is not linted, as well as fully qualified + // syntax +======= + // make sure `Aaa::deref` instead of `aaa.deref()` works as well as fully qualified syntax +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + // make sure `Aaa::deref` instead of `aaa.deref()` is not linted, as well as fully qualified + // syntax +>>>>>>> eed466281 (ignore `Foo::deref` altogether) + + Aaa::deref(&Aaa); + Aaa::deref_mut(&mut Aaa); + ::deref(&Aaa); + ::deref_mut(&mut Aaa); + let mut aaa = Aaa; + Aaa::deref(&aaa); + Aaa::deref_mut(&mut aaa); + // following should not require linting let cv = CustomVec(vec![0, 42]); diff --git a/tests/ui/explicit_deref_methods.stderr b/tests/ui/explicit_deref_methods.stderr index 4b10ed1377b0..205492aa9c9e 100644 --- a/tests/ui/explicit_deref_methods.stderr +++ b/tests/ui/explicit_deref_methods.stderr @@ -1,76 +1,212 @@ error: explicit `deref` method call - --> $DIR/explicit_deref_methods.rs:36:19 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:54:19 +======= + --> $DIR/explicit_deref_methods.rs:53:19 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:54:19 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let b: &str = a.deref(); - | ^^^^^^^^^ help: try this: `&*a` + | ^^^^^^^^^ help: try: `&*a` | = note: `-D clippy::explicit-deref-methods` implied by `-D warnings` error: explicit `deref_mut` method call - --> $DIR/explicit_deref_methods.rs:38:23 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:56:23 +======= + --> $DIR/explicit_deref_methods.rs:55:23 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:56:23 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let b: &mut str = a.deref_mut(); - | ^^^^^^^^^^^^^ help: try this: `&mut **a` + | ^^^^^^^^^^^^^ help: try: `&mut **a` error: explicit `deref` method call - --> $DIR/explicit_deref_methods.rs:41:39 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:59:39 +======= + --> $DIR/explicit_deref_methods.rs:58:39 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:59:39 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let b: String = format!("{}, {}", a.deref(), a.deref()); - | ^^^^^^^^^ help: try this: `&*a` + | ^^^^^^^^^ help: try: `&*a` error: explicit `deref` method call - --> $DIR/explicit_deref_methods.rs:41:50 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:59:50 +======= + --> $DIR/explicit_deref_methods.rs:58:50 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:59:50 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let b: String = format!("{}, {}", a.deref(), a.deref()); - | ^^^^^^^^^ help: try this: `&*a` + | ^^^^^^^^^ help: try: `&*a` error: explicit `deref` method call - --> $DIR/explicit_deref_methods.rs:43:20 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:61:20 +======= + --> $DIR/explicit_deref_methods.rs:60:20 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:61:20 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | println!("{}", a.deref()); - | ^^^^^^^^^ help: try this: `&*a` + | ^^^^^^^^^ help: try: `&*a` error: explicit `deref` method call - --> $DIR/explicit_deref_methods.rs:46:11 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:64:11 +======= + --> $DIR/explicit_deref_methods.rs:63:11 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:64:11 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | match a.deref() { - | ^^^^^^^^^ help: try this: `&*a` + | ^^^^^^^^^ help: try: `&*a` error: explicit `deref` method call - --> $DIR/explicit_deref_methods.rs:50:28 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:68:28 +======= + --> $DIR/explicit_deref_methods.rs:67:28 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:68:28 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let b: String = concat(a.deref()); - | ^^^^^^^^^ help: try this: `&*a` + | ^^^^^^^^^ help: try: `&*a` error: explicit `deref` method call - --> $DIR/explicit_deref_methods.rs:52:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:70:13 +======= + --> $DIR/explicit_deref_methods.rs:69:13 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:70:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let b = just_return(a).deref(); - | ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `just_return(a)` + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)` error: explicit `deref` method call - --> $DIR/explicit_deref_methods.rs:54:28 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:72:28 +======= + --> $DIR/explicit_deref_methods.rs:71:28 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:72:28 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let b: String = concat(just_return(a).deref()); - | ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `just_return(a)` + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)` error: explicit `deref` method call - --> $DIR/explicit_deref_methods.rs:56:19 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:74:19 +======= + --> $DIR/explicit_deref_methods.rs:73:19 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:74:19 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let b: &str = a.deref().deref(); - | ^^^^^^^^^^^^^^^^^ help: try this: `&**a` + | ^^^^^^^^^^^^^^^^^ help: try: `&**a` error: explicit `deref` method call - --> $DIR/explicit_deref_methods.rs:59:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:77:13 +======= + --> $DIR/explicit_deref_methods.rs:76:13 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:77:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let b = opt_a.unwrap().deref(); - | ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&*opt_a.unwrap()` + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*opt_a.unwrap()` error: explicit `deref` method call - --> $DIR/explicit_deref_methods.rs:85:31 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_deref_methods.rs:114:31 +======= + --> $DIR/explicit_deref_methods.rs:80:5 + | +LL | Aaa::deref(&Aaa); + | ^^^^^^^^^^^^^^^^ help: try this: `&*Aaa` + +error: explicit `deref_mut` method call + --> $DIR/explicit_deref_methods.rs:81:5 + | +LL | Aaa::deref_mut(&mut Aaa); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut *Aaa` + +error: explicit `deref` method call + --> $DIR/explicit_deref_methods.rs:82:5 + | +LL | ::deref(&Aaa); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&*Aaa` + +error: explicit `deref_mut` method call + --> $DIR/explicit_deref_methods.rs:83:5 + | +LL | ::deref_mut(&mut Aaa); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut *Aaa` + +error: explicit `deref` method call + --> $DIR/explicit_deref_methods.rs:85:5 + | +LL | Aaa::deref(&aaa); + | ^^^^^^^^^^^^^^^^ help: try this: `&*aaa` + +error: explicit `deref_mut` method call + --> $DIR/explicit_deref_methods.rs:86:5 + | +LL | Aaa::deref_mut(&mut aaa); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut *aaa` + +error: explicit `deref` method call + --> $DIR/explicit_deref_methods.rs:112:31 +>>>>>>> 8188da361 (Fix suggestion on fully qualified syntax) +======= + --> $DIR/explicit_deref_methods.rs:113:31 +>>>>>>> eed466281 (ignore `Foo::deref` altogether) +======= + --> $DIR/explicit_deref_methods.rs:114:31 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let b: &str = expr_deref!(a.deref()); - | ^^^^^^^^^ help: try this: `&*a` + | ^^^^^^^^^ help: try: `&*a` error: aborting due to 12 previous errors diff --git a/tests/ui/explicit_into_iter_loop.fixed b/tests/ui/explicit_into_iter_loop.fixed new file mode 100644 index 000000000000..8c9613f12dfc --- /dev/null +++ b/tests/ui/explicit_into_iter_loop.fixed @@ -0,0 +1,113 @@ +//@run-rustfix +#![warn(clippy::explicit_into_iter_loop)] + +fn main() { + // Issue #4958 + fn _takes_iterator(iterator: &T) + where + for<'a> &'a T: IntoIterator, + { +<<<<<<< HEAD +<<<<<<< HEAD + for _ in iterator {} +======= + for i in iterator { + println!("{}", i); + } +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + for _ in iterator {} +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + } + + struct T; + impl IntoIterator for &T { + type Item = (); + type IntoIter = std::vec::IntoIter; + fn into_iter(self) -> Self::IntoIter { +<<<<<<< HEAD +<<<<<<< HEAD + unimplemented!() + } + } + + let mut t = T; + for _ in &t {} + + let r = &t; +======= + vec![].into_iter() +======= + unimplemented!() +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + } + } + + let mut t = T; + for _ in &t {} + + let r = &t; +<<<<<<< HEAD + let rr = &&t; + + // This case is handled by `explicit_iter_loop`. No idea why. + for _ in t.into_iter() {} + +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + for _ in r {} + + // No suggestion for this. + // We'd have to suggest `for _ in *rr {}` which is less clear. +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + let rr = &&t; + for _ in rr.into_iter() {} + + let mr = &mut t; + for _ in &*mr {} + + struct U; + impl IntoIterator for &mut U { + type Item = (); + type IntoIter = std::vec::IntoIter; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + + let mut u = U; + for _ in &mut u {} + + let mr = &mut u; + for _ in &mut *mr {} + +<<<<<<< HEAD +======= + for _ in rr.into_iter() {} + +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + // Issue #6900 + struct S; + impl S { + #[allow(clippy::should_implement_trait)] + pub fn into_iter(self) -> I { + unimplemented!() + } + } + + struct I(T); + impl Iterator for I { + type Item = T; + fn next(&mut self) -> Option { + unimplemented!() + } + } + + for _ in S.into_iter::() {} +} diff --git a/tests/ui/explicit_into_iter_loop.rs b/tests/ui/explicit_into_iter_loop.rs new file mode 100644 index 000000000000..1c5041b136d1 --- /dev/null +++ b/tests/ui/explicit_into_iter_loop.rs @@ -0,0 +1,108 @@ +//@run-rustfix +#![warn(clippy::explicit_into_iter_loop)] + +fn main() { + // Issue #4958 + fn _takes_iterator(iterator: &T) + where + for<'a> &'a T: IntoIterator, + { +<<<<<<< HEAD +<<<<<<< HEAD + for _ in iterator.into_iter() {} +======= + for i in iterator.into_iter() { + println!("{}", i); + } +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + for _ in iterator.into_iter() {} +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + } + + struct T; + impl IntoIterator for &T { + type Item = (); + type IntoIter = std::vec::IntoIter; + fn into_iter(self) -> Self::IntoIter { +<<<<<<< HEAD +<<<<<<< HEAD + unimplemented!() + } + } + + let mut t = T; + for _ in t.into_iter() {} + + let r = &t; +======= + vec![].into_iter() +======= + unimplemented!() +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + } + } + + let mut t = T; + for _ in t.into_iter() {} + +<<<<<<< HEAD +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + let r = &t; +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + for _ in r.into_iter() {} + + // No suggestion for this. + // We'd have to suggest `for _ in *rr {}` which is less clear. +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + let rr = &&t; + for _ in rr.into_iter() {} + + let mr = &mut t; + for _ in mr.into_iter() {} + + struct U; + impl IntoIterator for &mut U { + type Item = (); + type IntoIter = std::vec::IntoIter; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + + let mut u = U; + for _ in u.into_iter() {} + + let mr = &mut u; + for _ in mr.into_iter() {} + +<<<<<<< HEAD +======= + for _ in rr.into_iter() {} + +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + // Issue #6900 + struct S; + impl S { + #[allow(clippy::should_implement_trait)] + pub fn into_iter(self) -> I { + unimplemented!() + } + } + + struct I(T); + impl Iterator for I { + type Item = T; + fn next(&mut self) -> Option { + unimplemented!() + } + } + + for _ in S.into_iter::() {} +} diff --git a/tests/ui/explicit_into_iter_loop.stderr b/tests/ui/explicit_into_iter_loop.stderr new file mode 100644 index 000000000000..b325ef2c9796 --- /dev/null +++ b/tests/ui/explicit_into_iter_loop.stderr @@ -0,0 +1,68 @@ +error: it is more concise to loop over containers instead of using explicit iteration methods + --> $DIR/explicit_into_iter_loop.rs:10:18 + | +<<<<<<< HEAD +<<<<<<< HEAD +LL | for _ in iterator.into_iter() {} +======= +LL | for i in iterator.into_iter() { +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +LL | for _ in iterator.into_iter() {} +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + | ^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `iterator` + | + = note: `-D clippy::explicit-into-iter-loop` implied by `-D warnings` + +error: it is more concise to loop over containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + --> $DIR/explicit_into_iter_loop.rs:23:14 + | +LL | for _ in t.into_iter() {} + | ^^^^^^^^^^^^^ help: to write this more concisely, try: `&t` + +error: it is more concise to loop over containers instead of using explicit iteration methods + --> $DIR/explicit_into_iter_loop.rs:26:14 +<<<<<<< HEAD +======= + --> $DIR/explicit_into_iter_loop.rs:31:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + | +LL | for _ in r.into_iter() {} + | ^^^^^^^^^^^^^ help: to write this more concisely, try: `r` + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) +error: it is more concise to loop over containers instead of using explicit iteration methods + --> $DIR/explicit_into_iter_loop.rs:34:14 + | +LL | for _ in mr.into_iter() {} + | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&*mr` + +error: it is more concise to loop over containers instead of using explicit iteration methods + --> $DIR/explicit_into_iter_loop.rs:46:14 + | +LL | for _ in u.into_iter() {} + | ^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut u` + +error: it is more concise to loop over containers instead of using explicit iteration methods + --> $DIR/explicit_into_iter_loop.rs:49:14 + | +LL | for _ in mr.into_iter() {} + | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *mr` + +error: aborting due to 6 previous errors +<<<<<<< HEAD +======= +error: aborting due to 2 previous errors +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 482baf2bc (Fix `explicit_into_iter_loop` with mutable references) + diff --git a/tests/ui/explicit_iter_loop.fixed b/tests/ui/explicit_iter_loop.fixed new file mode 100644 index 000000000000..4a92922cf27e --- /dev/null +++ b/tests/ui/explicit_iter_loop.fixed @@ -0,0 +1,184 @@ +//@run-rustfix +#![deny(clippy::explicit_iter_loop)] +#![allow( + clippy::linkedlist, + clippy::similar_names, + clippy::needless_borrow, + clippy::deref_addrof, + dead_code +)] + +use core::slice; +use std::collections::*; + +fn main() { + let mut vec = vec![1, 2, 3, 4]; + + for _ in &vec {} + for _ in &mut vec {} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + let rvec = &vec; + for _ in rvec {} + + let rmvec = &mut vec; + for _ in &*rmvec {} + for _ in &mut *rmvec {} + +<<<<<<< HEAD +======= +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + for _ in &vec {} // these are fine + for _ in &mut vec {} // these are fine + + for _ in &[1, 2, 3] {} + + for _ in &*(&mut [1, 2, 3]) {} + + for _ in &[0; 32] {} + for _ in &[0; 33] {} + + let ll: LinkedList<()> = LinkedList::new(); + for _ in &ll {} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + let rll = ≪ + for _ in rll {} + + let vd: VecDeque<()> = VecDeque::new(); + for _ in &vd {} + let rvd = &vd; + for _ in rvd {} +<<<<<<< HEAD +======= + + let vd: VecDeque<()> = VecDeque::new(); + for _ in &vd {} +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + + let bh: BinaryHeap<()> = BinaryHeap::new(); + for _ in &bh {} + + let hm: HashMap<(), ()> = HashMap::new(); + for _ in &hm {} + + let bt: BTreeMap<(), ()> = BTreeMap::new(); + for _ in &bt {} + + let hs: HashSet<()> = HashSet::new(); + for _ in &hs {} + + let bs: BTreeSet<()> = BTreeSet::new(); + for _ in &bs {} + + struct NoIntoIter(); + impl NoIntoIter { + fn iter(&self) -> slice::Iter { + unimplemented!() + } + + fn iter_mut(&mut self) -> slice::IterMut { + unimplemented!() + } + } + let mut x = NoIntoIter(); + for _ in x.iter() {} // no error + for _ in x.iter_mut() {} // no error + + struct IntoIterDiffTy; + impl IntoIterator for &'_ IntoIterDiffTy { + type Item = &'static (); + type IntoIter = core::slice::Iter<'static, ()>; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + impl IntoIterDiffTy { + fn iter(&self) -> core::slice::Iter<'static, i32> { + unimplemented!() + } + } + let x = IntoIterDiffTy; + for _ in x.iter() {} + + struct IntoIterDiffSig; + impl IntoIterator for &'_ IntoIterDiffSig { + type Item = &'static (); + type IntoIter = core::slice::Iter<'static, ()>; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + impl IntoIterDiffSig { + fn iter(&self, _: u32) -> core::slice::Iter<'static, ()> { + unimplemented!() + } + } + let x = IntoIterDiffSig; + for _ in x.iter(0) {} + + struct IntoIterDiffLt<'a>(&'a ()); + impl<'a> IntoIterator for &'a IntoIterDiffLt<'_> { + type Item = &'a (); + type IntoIter = core::slice::Iter<'a, ()>; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + impl<'a> IntoIterDiffLt<'a> { + fn iter(&self) -> core::slice::Iter<'a, ()> { + unimplemented!() + } + } + let x = IntoIterDiffLt(&()); + for _ in x.iter() {} + + struct CustomType; + impl<'a> IntoIterator for &'a CustomType { + type Item = &'a u32; + type IntoIter = core::slice::Iter<'a, u32>; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + impl<'a> IntoIterator for &'a mut CustomType { + type Item = &'a mut u32; + type IntoIter = core::slice::IterMut<'a, u32>; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + impl CustomType { + fn iter(&self) -> <&'_ Self as IntoIterator>::IntoIter { + panic!() + } + + fn iter_mut(&mut self) -> core::slice::IterMut<'_, u32> { + panic!() + } + } + let mut x = CustomType; + for _ in &x {} + for _ in &mut x {} +<<<<<<< HEAD +<<<<<<< HEAD + + let r = &x; + for _ in r {} +======= +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + + let r = &x; + for _ in r {} +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) +} diff --git a/tests/ui/explicit_iter_loop.rs b/tests/ui/explicit_iter_loop.rs new file mode 100644 index 000000000000..51d9fe9da1f2 --- /dev/null +++ b/tests/ui/explicit_iter_loop.rs @@ -0,0 +1,184 @@ +//@run-rustfix +#![deny(clippy::explicit_iter_loop)] +#![allow( + clippy::linkedlist, + clippy::similar_names, + clippy::needless_borrow, + clippy::deref_addrof, + dead_code +)] + +use core::slice; +use std::collections::*; + +fn main() { + let mut vec = vec![1, 2, 3, 4]; + + for _ in vec.iter() {} + for _ in vec.iter_mut() {} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + let rvec = &vec; + for _ in rvec.iter() {} + + let rmvec = &mut vec; + for _ in rmvec.iter() {} + for _ in rmvec.iter_mut() {} + +<<<<<<< HEAD +======= +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + for _ in &vec {} // these are fine + for _ in &mut vec {} // these are fine + + for _ in [1, 2, 3].iter() {} + + for _ in (&mut [1, 2, 3]).iter() {} + + for _ in [0; 32].iter() {} + for _ in [0; 33].iter() {} + + let ll: LinkedList<()> = LinkedList::new(); + for _ in ll.iter() {} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + let rll = ≪ + for _ in rll.iter() {} + + let vd: VecDeque<()> = VecDeque::new(); + for _ in vd.iter() {} + let rvd = &vd; + for _ in rvd.iter() {} +<<<<<<< HEAD +======= + + let vd: VecDeque<()> = VecDeque::new(); + for _ in vd.iter() {} +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + + let bh: BinaryHeap<()> = BinaryHeap::new(); + for _ in bh.iter() {} + + let hm: HashMap<(), ()> = HashMap::new(); + for _ in hm.iter() {} + + let bt: BTreeMap<(), ()> = BTreeMap::new(); + for _ in bt.iter() {} + + let hs: HashSet<()> = HashSet::new(); + for _ in hs.iter() {} + + let bs: BTreeSet<()> = BTreeSet::new(); + for _ in bs.iter() {} + + struct NoIntoIter(); + impl NoIntoIter { + fn iter(&self) -> slice::Iter { + unimplemented!() + } + + fn iter_mut(&mut self) -> slice::IterMut { + unimplemented!() + } + } + let mut x = NoIntoIter(); + for _ in x.iter() {} // no error + for _ in x.iter_mut() {} // no error + + struct IntoIterDiffTy; + impl IntoIterator for &'_ IntoIterDiffTy { + type Item = &'static (); + type IntoIter = core::slice::Iter<'static, ()>; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + impl IntoIterDiffTy { + fn iter(&self) -> core::slice::Iter<'static, i32> { + unimplemented!() + } + } + let x = IntoIterDiffTy; + for _ in x.iter() {} + + struct IntoIterDiffSig; + impl IntoIterator for &'_ IntoIterDiffSig { + type Item = &'static (); + type IntoIter = core::slice::Iter<'static, ()>; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + impl IntoIterDiffSig { + fn iter(&self, _: u32) -> core::slice::Iter<'static, ()> { + unimplemented!() + } + } + let x = IntoIterDiffSig; + for _ in x.iter(0) {} + + struct IntoIterDiffLt<'a>(&'a ()); + impl<'a> IntoIterator for &'a IntoIterDiffLt<'_> { + type Item = &'a (); + type IntoIter = core::slice::Iter<'a, ()>; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + impl<'a> IntoIterDiffLt<'a> { + fn iter(&self) -> core::slice::Iter<'a, ()> { + unimplemented!() + } + } + let x = IntoIterDiffLt(&()); + for _ in x.iter() {} + + struct CustomType; + impl<'a> IntoIterator for &'a CustomType { + type Item = &'a u32; + type IntoIter = core::slice::Iter<'a, u32>; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + impl<'a> IntoIterator for &'a mut CustomType { + type Item = &'a mut u32; + type IntoIter = core::slice::IterMut<'a, u32>; + fn into_iter(self) -> Self::IntoIter { + unimplemented!() + } + } + impl CustomType { + fn iter(&self) -> <&'_ Self as IntoIterator>::IntoIter { + panic!() + } + + fn iter_mut(&mut self) -> core::slice::IterMut<'_, u32> { + panic!() + } + } + let mut x = CustomType; + for _ in x.iter() {} + for _ in x.iter_mut() {} +<<<<<<< HEAD +<<<<<<< HEAD + + let r = &x; + for _ in r.iter() {} +======= +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + + let r = &x; + for _ in r.iter() {} +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) +} diff --git a/tests/ui/explicit_iter_loop.stderr b/tests/ui/explicit_iter_loop.stderr new file mode 100644 index 000000000000..ba72617c685f --- /dev/null +++ b/tests/ui/explicit_iter_loop.stderr @@ -0,0 +1,270 @@ +error: it is more concise to loop over references to containers instead of using explicit iteration methods + --> $DIR/explicit_iter_loop.rs:17:14 + | +LL | for _ in vec.iter() {} + | ^^^^^^^^^^ help: to write this more concisely, try: `&vec` + | +note: the lint level is defined here + --> $DIR/explicit_iter_loop.rs:2:9 + | +LL | #![deny(clippy::explicit_iter_loop)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: it is more concise to loop over references to containers instead of using explicit iteration methods + --> $DIR/explicit_iter_loop.rs:18:14 + | +LL | for _ in vec.iter_mut() {} + | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut vec` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + --> $DIR/explicit_iter_loop.rs:21:14 + | +LL | for _ in rvec.iter() {} + | ^^^^^^^^^^^ help: to write this more concisely, try: `rvec` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods + --> $DIR/explicit_iter_loop.rs:24:14 + | +LL | for _ in rmvec.iter() {} + | ^^^^^^^^^^^^ help: to write this more concisely, try: `&*rmvec` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods + --> $DIR/explicit_iter_loop.rs:25:14 + | +LL | for _ in rmvec.iter_mut() {} + | ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *rmvec` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods + --> $DIR/explicit_iter_loop.rs:30:14 +<<<<<<< HEAD +======= + --> $DIR/explicit_iter_loop.rs:23:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in [1, 2, 3].iter() {} + | ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[1, 2, 3]` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_iter_loop.rs:32:14 +======= + --> $DIR/explicit_iter_loop.rs:25:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + --> $DIR/explicit_iter_loop.rs:32:14 +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in (&mut [1, 2, 3]).iter() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&*(&mut [1, 2, 3])` + +error: the method `iter` doesn't need a mutable reference +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_iter_loop.rs:32:14 +======= + --> $DIR/explicit_iter_loop.rs:25:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + --> $DIR/explicit_iter_loop.rs:32:14 +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in (&mut [1, 2, 3]).iter() {} + | ^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::unnecessary-mut-passed` implied by `-D warnings` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_iter_loop.rs:34:14 +======= + --> $DIR/explicit_iter_loop.rs:27:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + --> $DIR/explicit_iter_loop.rs:34:14 +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in [0; 32].iter() {} + | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 32]` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_iter_loop.rs:35:14 +======= + --> $DIR/explicit_iter_loop.rs:28:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + --> $DIR/explicit_iter_loop.rs:35:14 +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in [0; 33].iter() {} + | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 33]` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_iter_loop.rs:38:14 +======= + --> $DIR/explicit_iter_loop.rs:31:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + --> $DIR/explicit_iter_loop.rs:38:14 +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in ll.iter() {} + | ^^^^^^^^^ help: to write this more concisely, try: `&ll` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + --> $DIR/explicit_iter_loop.rs:40:14 + | +LL | for _ in rll.iter() {} + | ^^^^^^^^^^ help: to write this more concisely, try: `rll` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods + --> $DIR/explicit_iter_loop.rs:43:14 +<<<<<<< HEAD +======= + --> $DIR/explicit_iter_loop.rs:34:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in vd.iter() {} + | ^^^^^^^^^ help: to write this more concisely, try: `&vd` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + --> $DIR/explicit_iter_loop.rs:45:14 + | +LL | for _ in rvd.iter() {} + | ^^^^^^^^^^ help: to write this more concisely, try: `rvd` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods + --> $DIR/explicit_iter_loop.rs:48:14 +<<<<<<< HEAD +======= + --> $DIR/explicit_iter_loop.rs:37:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in bh.iter() {} + | ^^^^^^^^^ help: to write this more concisely, try: `&bh` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_iter_loop.rs:51:14 +======= + --> $DIR/explicit_iter_loop.rs:40:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + --> $DIR/explicit_iter_loop.rs:51:14 +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in hm.iter() {} + | ^^^^^^^^^ help: to write this more concisely, try: `&hm` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_iter_loop.rs:54:14 +======= + --> $DIR/explicit_iter_loop.rs:43:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + --> $DIR/explicit_iter_loop.rs:54:14 +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in bt.iter() {} + | ^^^^^^^^^ help: to write this more concisely, try: `&bt` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_iter_loop.rs:57:14 +======= + --> $DIR/explicit_iter_loop.rs:46:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + --> $DIR/explicit_iter_loop.rs:57:14 +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in hs.iter() {} + | ^^^^^^^^^ help: to write this more concisely, try: `&hs` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_iter_loop.rs:60:14 +======= + --> $DIR/explicit_iter_loop.rs:49:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + --> $DIR/explicit_iter_loop.rs:60:14 +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in bs.iter() {} + | ^^^^^^^^^ help: to write this more concisely, try: `&bs` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_iter_loop.rs:149:14 +======= + --> $DIR/explicit_iter_loop.rs:138:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + --> $DIR/explicit_iter_loop.rs:149:14 +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in x.iter() {} + | ^^^^^^^^ help: to write this more concisely, try: `&x` + +error: it is more concise to loop over references to containers instead of using explicit iteration methods +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/explicit_iter_loop.rs:150:14 +======= + --> $DIR/explicit_iter_loop.rs:139:14 +>>>>>>> 974900b50 (Split `for_loops` tests) +======= + --> $DIR/explicit_iter_loop.rs:150:14 +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + | +LL | for _ in x.iter_mut() {} + | ^^^^^^^^^^^^ help: to write this more concisely, try: `&mut x` + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) +error: it is more concise to loop over references to containers instead of using explicit iteration methods + --> $DIR/explicit_iter_loop.rs:153:14 + | +LL | for _ in r.iter() {} + | ^^^^^^^^ help: to write this more concisely, try: `r` + +error: aborting due to 22 previous errors +<<<<<<< HEAD +======= +error: aborting due to 16 previous errors +>>>>>>> 974900b50 (Split `for_loops` tests) +======= +>>>>>>> 949712c90 (Reborrow mutable references in `explicit_iter_loop`) + diff --git a/tests/ui/explicit_write.fixed b/tests/ui/explicit_write.fixed index 862c3fea9ee8..213485bc221b 100644 --- a/tests/ui/explicit_write.fixed +++ b/tests/ui/explicit_write.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::explicit_write)] #![allow(unused_imports)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/explicit_write.rs b/tests/ui/explicit_write.rs index 41d7c2255738..64acd7108bfa 100644 --- a/tests/ui/explicit_write.rs +++ b/tests/ui/explicit_write.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::explicit_write)] #![allow(unused_imports)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/explicit_write.stderr b/tests/ui/explicit_write.stderr index 457e9c627180..b3aa7274c6d0 100644 --- a/tests/ui/explicit_write.stderr +++ b/tests/ui/explicit_write.stderr @@ -2,7 +2,7 @@ error: use of `write!(stdout(), ...).unwrap()` --> $DIR/explicit_write.rs:24:9 | LL | write!(std::io::stdout(), "test").unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `print!("test")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `print!("test")` | = note: `-D clippy::explicit-write` implied by `-D warnings` @@ -10,73 +10,73 @@ error: use of `write!(stderr(), ...).unwrap()` --> $DIR/explicit_write.rs:25:9 | LL | write!(std::io::stderr(), "test").unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprint!("test")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprint!("test")` error: use of `writeln!(stdout(), ...).unwrap()` --> $DIR/explicit_write.rs:26:9 | LL | writeln!(std::io::stdout(), "test").unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `println!("test")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `println!("test")` error: use of `writeln!(stderr(), ...).unwrap()` --> $DIR/explicit_write.rs:27:9 | LL | writeln!(std::io::stderr(), "test").unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("test")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("test")` error: use of `stdout().write_fmt(...).unwrap()` --> $DIR/explicit_write.rs:28:9 | LL | std::io::stdout().write_fmt(format_args!("test")).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `print!("test")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `print!("test")` error: use of `stderr().write_fmt(...).unwrap()` --> $DIR/explicit_write.rs:29:9 | LL | std::io::stderr().write_fmt(format_args!("test")).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprint!("test")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprint!("test")` error: use of `writeln!(stdout(), ...).unwrap()` --> $DIR/explicit_write.rs:32:9 | LL | writeln!(std::io::stdout(), "test/ntest").unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `println!("test/ntest")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `println!("test/ntest")` error: use of `writeln!(stderr(), ...).unwrap()` --> $DIR/explicit_write.rs:33:9 | LL | writeln!(std::io::stderr(), "test/ntest").unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("test/ntest")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("test/ntest")` error: use of `writeln!(stderr(), ...).unwrap()` --> $DIR/explicit_write.rs:36:9 | LL | writeln!(std::io::stderr(), "with {}", value).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("with {}", value)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("with {}", value)` error: use of `writeln!(stderr(), ...).unwrap()` --> $DIR/explicit_write.rs:37:9 | LL | writeln!(std::io::stderr(), "with {} {}", 2, value).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("with {} {}", 2, value)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("with {} {}", 2, value)` error: use of `writeln!(stderr(), ...).unwrap()` --> $DIR/explicit_write.rs:38:9 | LL | writeln!(std::io::stderr(), "with {value}").unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("with {value}")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("with {value}")` error: use of `writeln!(stderr(), ...).unwrap()` --> $DIR/explicit_write.rs:39:9 | LL | writeln!(std::io::stderr(), "macro arg {}", one!()).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("macro arg {}", one!())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("macro arg {}", one!())` error: use of `writeln!(stderr(), ...).unwrap()` --> $DIR/explicit_write.rs:41:9 | LL | writeln!(std::io::stderr(), "{:w$}", value, w = width).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("{:w$}", value, w = width)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("{:w$}", value, w = width)` error: aborting due to 13 previous errors diff --git a/tests/ui/extend_with_drain.fixed b/tests/ui/extend_with_drain.fixed index 71ebad24c16e..594f2f6d4135 100644 --- a/tests/ui/extend_with_drain.fixed +++ b/tests/ui/extend_with_drain.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::extend_with_drain)] #![allow(clippy::iter_with_drain)] use std::collections::BinaryHeap; diff --git a/tests/ui/extend_with_drain.rs b/tests/ui/extend_with_drain.rs index e9f011abb0e8..3e2ad02052d7 100644 --- a/tests/ui/extend_with_drain.rs +++ b/tests/ui/extend_with_drain.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::extend_with_drain)] #![allow(clippy::iter_with_drain)] use std::collections::BinaryHeap; diff --git a/tests/ui/extend_with_drain.stderr b/tests/ui/extend_with_drain.stderr index da14ddb25b37..eb2dd304d370 100644 --- a/tests/ui/extend_with_drain.stderr +++ b/tests/ui/extend_with_drain.stderr @@ -2,7 +2,7 @@ error: use of `extend` instead of `append` for adding the full range of a second --> $DIR/extend_with_drain.rs:9:5 | LL | vec2.extend(vec1.drain(..)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec2.append(&mut vec1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec2.append(&mut vec1)` | = note: `-D clippy::extend-with-drain` implied by `-D warnings` @@ -10,19 +10,19 @@ error: use of `extend` instead of `append` for adding the full range of a second --> $DIR/extend_with_drain.rs:14:5 | LL | vec4.extend(vec3.drain(..)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec4.append(&mut vec3)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec4.append(&mut vec3)` error: use of `extend` instead of `append` for adding the full range of a second vector --> $DIR/extend_with_drain.rs:18:5 | LL | vec11.extend(return_vector().drain(..)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec11.append(&mut return_vector())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec11.append(&mut return_vector())` error: use of `extend` instead of `append` for adding the full range of a second vector --> $DIR/extend_with_drain.rs:49:5 | LL | y.extend(ref_x.drain(..)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `y.append(ref_x)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `y.append(ref_x)` error: aborting due to 4 previous errors diff --git a/tests/ui/extra_unused_lifetimes.rs b/tests/ui/extra_unused_lifetimes.rs index d6631e012900..53b6e5d243b0 100644 --- a/tests/ui/extra_unused_lifetimes.rs +++ b/tests/ui/extra_unused_lifetimes.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macro_derive.rs +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow( unused, diff --git a/tests/ui/extra_unused_type_parameters.fixed b/tests/ui/extra_unused_type_parameters.fixed index 19e718625582..f324f3512a8b 100644 --- a/tests/ui/extra_unused_type_parameters.fixed +++ b/tests/ui/extra_unused_type_parameters.fixed @@ -1,8 +1,41 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +<<<<<<< HEAD +======= // run-rustfix +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +//@run-rustfix +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +//@run-rustfix +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> f0eb40c98 (Avoid linting on procedural macros) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) #![allow(unused, clippy::needless_lifetimes)] #![warn(clippy::extra_unused_type_parameters)] +extern crate proc_macros; +use proc_macros::with_span; + fn unused_ty(x: u8) { unimplemented!() } @@ -102,4 +135,12 @@ mod issue10319 { } } +with_span!( + span + + fn should_not_lint(x: u8) { + unimplemented!() + } +); + fn main() {} diff --git a/tests/ui/extra_unused_type_parameters.rs b/tests/ui/extra_unused_type_parameters.rs index e53bb587e89a..96ed61cbcb9c 100644 --- a/tests/ui/extra_unused_type_parameters.rs +++ b/tests/ui/extra_unused_type_parameters.rs @@ -1,8 +1,41 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +<<<<<<< HEAD +======= // run-rustfix +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +//@run-rustfix +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +//@run-rustfix +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> f0eb40c98 (Avoid linting on procedural macros) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) #![allow(unused, clippy::needless_lifetimes)] #![warn(clippy::extra_unused_type_parameters)] +extern crate proc_macros; +use proc_macros::with_span; + fn unused_ty(x: u8) { unimplemented!() } @@ -102,4 +135,12 @@ mod issue10319 { } } +with_span!( + span + + fn should_not_lint(x: u8) { + unimplemented!() + } +); + fn main() {} diff --git a/tests/ui/extra_unused_type_parameters.stderr b/tests/ui/extra_unused_type_parameters.stderr index c042a5a2290e..b5277d49861c 100644 --- a/tests/ui/extra_unused_type_parameters.stderr +++ b/tests/ui/extra_unused_type_parameters.stderr @@ -1,5 +1,5 @@ error: type parameter `T` goes unused in function definition - --> $DIR/extra_unused_type_parameters.rs:6:13 + --> $DIR/extra_unused_type_parameters.rs:10:13 | LL | fn unused_ty(x: u8) { | ^^^ help: consider removing the parameter @@ -7,19 +7,19 @@ LL | fn unused_ty(x: u8) { = note: `-D clippy::extra-unused-type-parameters` implied by `-D warnings` error: type parameters go unused in function definition: T, U - --> $DIR/extra_unused_type_parameters.rs:10:16 + --> $DIR/extra_unused_type_parameters.rs:14:16 | LL | fn unused_multi(x: u8) { | ^^^^^^ help: consider removing the parameters error: type parameter `T` goes unused in function definition - --> $DIR/extra_unused_type_parameters.rs:14:21 + --> $DIR/extra_unused_type_parameters.rs:18:21 | LL | fn unused_with_lt<'a, T>(x: &'a u8) { | ^^^ help: consider removing the parameter error: type parameters go unused in function definition: T, V - --> $DIR/extra_unused_type_parameters.rs:26:19 + --> $DIR/extra_unused_type_parameters.rs:30:19 | LL | fn unused_bounded(x: U) { | ^^^^^^^^^^^^ ^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL + fn unused_bounded(x: U) { | error: type parameters go unused in function definition: A, D, E - --> $DIR/extra_unused_type_parameters.rs:30:16 + --> $DIR/extra_unused_type_parameters.rs:34:16 | LL | fn some_unused, E>(b: B, c: C) { | ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,19 +43,19 @@ LL + fn some_unused(b: B, c: C) { | error: type parameter `T` goes unused in function definition - --> $DIR/extra_unused_type_parameters.rs:55:22 + --> $DIR/extra_unused_type_parameters.rs:59:22 | LL | fn unused_ty_impl(&self) { | ^^^ help: consider removing the parameter error: type parameters go unused in function definition: A, B - --> $DIR/extra_unused_type_parameters.rs:77:17 + --> $DIR/extra_unused_type_parameters.rs:81:17 | LL | fn unused_opaque(dummy: impl Default) { | ^^^^^^ help: consider removing the parameters error: type parameter `U` goes unused in function definition - --> $DIR/extra_unused_type_parameters.rs:90:56 + --> $DIR/extra_unused_type_parameters.rs:94:56 | LL | fn unused_with_priv_trait_bound() { | ^^^ help: consider removing the parameter diff --git a/tests/ui/field_reassign_with_default.rs b/tests/ui/field_reassign_with_default.rs index 0e208b3ed0e1..faddca70a5e9 100644 --- a/tests/ui/field_reassign_with_default.rs +++ b/tests/ui/field_reassign_with_default.rs @@ -1,5 +1,10 @@ -// aux-build:proc_macro_derive.rs -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::field_reassign_with_default)] diff --git a/tests/ui/filetype_is_file.rs b/tests/ui/filetype_is_file.rs index 5de8fe8cdd7b..d3ad36e40b53 100644 --- a/tests/ui/filetype_is_file.rs +++ b/tests/ui/filetype_is_file.rs @@ -1,3 +1,4 @@ +#![allow(clippy::needless_if)] #![warn(clippy::filetype_is_file)] fn main() -> std::io::Result<()> { diff --git a/tests/ui/filetype_is_file.stderr b/tests/ui/filetype_is_file.stderr index e51a90d6cfd2..36142deb3092 100644 --- a/tests/ui/filetype_is_file.stderr +++ b/tests/ui/filetype_is_file.stderr @@ -1,5 +1,5 @@ error: `FileType::is_file()` only covers regular files - --> $DIR/filetype_is_file.rs:8:8 + --> $DIR/filetype_is_file.rs:9:8 | LL | if fs::metadata("foo.txt")?.file_type().is_file() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | if fs::metadata("foo.txt")?.file_type().is_file() { = note: `-D clippy::filetype-is-file` implied by `-D warnings` error: `!FileType::is_file()` only denies regular files - --> $DIR/filetype_is_file.rs:13:8 + --> $DIR/filetype_is_file.rs:14:8 | LL | if !fs::metadata("foo.txt")?.file_type().is_file() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | if !fs::metadata("foo.txt")?.file_type().is_file() { = help: use `FileType::is_dir()` instead error: `FileType::is_file()` only covers regular files - --> $DIR/filetype_is_file.rs:18:9 + --> $DIR/filetype_is_file.rs:19:9 | LL | if !fs::metadata("foo.txt")?.file_type().is_file().bitor(true) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/filter_map_identity.fixed b/tests/ui/filter_map_identity.fixed index a5860aa49b3b..44665b451ada 100644 --- a/tests/ui/filter_map_identity.fixed +++ b/tests/ui/filter_map_identity.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports, clippy::needless_return)] #![warn(clippy::filter_map_identity)] diff --git a/tests/ui/filter_map_identity.rs b/tests/ui/filter_map_identity.rs index 7e998b9cdf70..9832acb013f8 100644 --- a/tests/ui/filter_map_identity.rs +++ b/tests/ui/filter_map_identity.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports, clippy::needless_return)] #![warn(clippy::filter_map_identity)] diff --git a/tests/ui/filter_map_next_fixable.fixed b/tests/ui/filter_map_next_fixable.fixed index 462d46169fcb..efb37f8b1b73 100644 --- a/tests/ui/filter_map_next_fixable.fixed +++ b/tests/ui/filter_map_next_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::pedantic)] #![allow(unused)] diff --git a/tests/ui/filter_map_next_fixable.rs b/tests/ui/filter_map_next_fixable.rs index 2ea00cf73072..b10e20d359ed 100644 --- a/tests/ui/filter_map_next_fixable.rs +++ b/tests/ui/filter_map_next_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::pedantic)] #![allow(unused)] diff --git a/tests/ui/filter_map_next_fixable.stderr b/tests/ui/filter_map_next_fixable.stderr index a9fc6abe88fa..26d9c5e19da7 100644 --- a/tests/ui/filter_map_next_fixable.stderr +++ b/tests/ui/filter_map_next_fixable.stderr @@ -2,7 +2,7 @@ error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly --> $DIR/filter_map_next_fixable.rs:9:32 | LL | let element: Option = a.iter().filter_map(|s| s.parse().ok()).next(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `a.iter().find_map(|s| s.parse().ok())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.iter().find_map(|s| s.parse().ok())` | = note: `-D clippy::filter-map-next` implied by `-D warnings` @@ -10,7 +10,7 @@ error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly --> $DIR/filter_map_next_fixable.rs:22:26 | LL | let _: Option = a.iter().filter_map(|s| s.parse().ok()).next(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `a.iter().find_map(|s| s.parse().ok())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.iter().find_map(|s| s.parse().ok())` error: aborting due to 2 previous errors diff --git a/tests/ui/find_map.rs b/tests/ui/find_map.rs index 88d3b0e74900..bbd395d50ef2 100644 --- a/tests/ui/find_map.rs +++ b/tests/ui/find_map.rs @@ -1,4 +1,5 @@ #![warn(clippy::all, clippy::pedantic)] +#![allow(clippy::useless_vec)] #[derive(Debug, Copy, Clone)] enum Flavor { diff --git a/tests/ui/flat_map_identity.fixed b/tests/ui/flat_map_identity.fixed index 1f4b880ef5bc..97091d6f1a5b 100644 --- a/tests/ui/flat_map_identity.fixed +++ b/tests/ui/flat_map_identity.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports, clippy::needless_return)] #![warn(clippy::flat_map_identity)] diff --git a/tests/ui/flat_map_identity.rs b/tests/ui/flat_map_identity.rs index de14a06d4e6b..5607683a5d04 100644 --- a/tests/ui/flat_map_identity.rs +++ b/tests/ui/flat_map_identity.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports, clippy::needless_return)] #![warn(clippy::flat_map_identity)] diff --git a/tests/ui/flat_map_option.fixed b/tests/ui/flat_map_option.fixed index 6a34f008995c..eeab864c42ff 100644 --- a/tests/ui/flat_map_option.fixed +++ b/tests/ui/flat_map_option.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::flat_map_option)] #![allow(clippy::redundant_closure, clippy::unnecessary_filter_map)] diff --git a/tests/ui/flat_map_option.rs b/tests/ui/flat_map_option.rs index 2479abddbf04..ebc389f7f029 100644 --- a/tests/ui/flat_map_option.rs +++ b/tests/ui/flat_map_option.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::flat_map_option)] #![allow(clippy::redundant_closure, clippy::unnecessary_filter_map)] diff --git a/tests/ui/float_arithmetic.rs b/tests/ui/float_arithmetic.rs index 60fa7569eb9d..a928c35e8bc9 100644 --- a/tests/ui/float_arithmetic.rs +++ b/tests/ui/float_arithmetic.rs @@ -1,4 +1,4 @@ -#![warn(clippy::integer_arithmetic, clippy::float_arithmetic)] +#![warn(clippy::arithmetic_side_effects, clippy::float_arithmetic)] #![allow( unused, clippy::shadow_reuse, diff --git a/tests/ui/floating_point_abs.fixed b/tests/ui/floating_point_abs.fixed index ca747fefc646..0cc572822e77 100644 --- a/tests/ui/floating_point_abs.fixed +++ b/tests/ui/floating_point_abs.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/tests/ui/floating_point_abs.rs b/tests/ui/floating_point_abs.rs index e4b606574979..6c732d398f06 100644 --- a/tests/ui/floating_point_abs.rs +++ b/tests/ui/floating_point_abs.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/tests/ui/floating_point_arithmetic_nostd.rs b/tests/ui/floating_point_arithmetic_nostd.rs new file mode 100644 index 000000000000..a42c6383ccea --- /dev/null +++ b/tests/ui/floating_point_arithmetic_nostd.rs @@ -0,0 +1,31 @@ +#![feature(lang_items, start)] +#![warn(clippy::imprecise_flops)] +#![warn(clippy::suboptimal_flops)] +#![no_std] + +// The following should not lint, as the suggested methods {f32,f64}.mul_add() +// and {f32,f64}::abs() are not available in no_std + +pub fn mul_add() { + let a: f64 = 1234.567; + let b: f64 = 45.67834; + let c: f64 = 0.0004; + let _ = a * b + c; +} + +fn fake_abs1(num: f64) -> f64 { + if num >= 0.0 { num } else { -num } +} + +#[start] +fn main(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[lang = "eh_personality"] +extern "C" fn eh_personality() {} diff --git a/tests/ui/floating_point_exp.fixed b/tests/ui/floating_point_exp.fixed index b9e3d89c2b29..1a33b8153eca 100644 --- a/tests/ui/floating_point_exp.fixed +++ b/tests/ui/floating_point_exp.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/tests/ui/floating_point_exp.rs b/tests/ui/floating_point_exp.rs index ef008dd9be05..4f4a5ec81ac9 100644 --- a/tests/ui/floating_point_exp.rs +++ b/tests/ui/floating_point_exp.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/tests/ui/floating_point_hypot.fixed b/tests/ui/floating_point_hypot.fixed index bbe411b3f488..431cb2709787 100644 --- a/tests/ui/floating_point_hypot.fixed +++ b/tests/ui/floating_point_hypot.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::imprecise_flops)] fn main() { diff --git a/tests/ui/floating_point_hypot.rs b/tests/ui/floating_point_hypot.rs index 586fd170ea14..e5506ed391c0 100644 --- a/tests/ui/floating_point_hypot.rs +++ b/tests/ui/floating_point_hypot.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::imprecise_flops)] fn main() { diff --git a/tests/ui/floating_point_log.fixed b/tests/ui/floating_point_log.fixed index ee5406461600..6582c0a0f6c8 100644 --- a/tests/ui/floating_point_log.fixed +++ b/tests/ui/floating_point_log.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)] #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] diff --git a/tests/ui/floating_point_log.rs b/tests/ui/floating_point_log.rs index 0590670a50bc..854d269fff59 100644 --- a/tests/ui/floating_point_log.rs +++ b/tests/ui/floating_point_log.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)] #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] diff --git a/tests/ui/floating_point_logbase.fixed b/tests/ui/floating_point_logbase.fixed index 7347bf72cbea..0783ecee1eec 100644 --- a/tests/ui/floating_point_logbase.fixed +++ b/tests/ui/floating_point_logbase.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/tests/ui/floating_point_logbase.rs b/tests/ui/floating_point_logbase.rs index ba5b8d406928..80fcfab68252 100644 --- a/tests/ui/floating_point_logbase.rs +++ b/tests/ui/floating_point_logbase.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/tests/ui/floating_point_mul_add.fixed b/tests/ui/floating_point_mul_add.fixed index d3e536ba3500..8848981a11d8 100644 --- a/tests/ui/floating_point_mul_add.fixed +++ b/tests/ui/floating_point_mul_add.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/tests/ui/floating_point_mul_add.rs b/tests/ui/floating_point_mul_add.rs index 5d4a9e35cfc2..b0edf5cb210c 100644 --- a/tests/ui/floating_point_mul_add.rs +++ b/tests/ui/floating_point_mul_add.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/tests/ui/floating_point_powf.fixed b/tests/ui/floating_point_powf.fixed index f7f93de29577..1e660b140c58 100644 --- a/tests/ui/floating_point_powf.fixed +++ b/tests/ui/floating_point_powf.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/tests/ui/floating_point_powf.rs b/tests/ui/floating_point_powf.rs index 499fc0e15e47..71c2f5292053 100644 --- a/tests/ui/floating_point_powf.rs +++ b/tests/ui/floating_point_powf.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/tests/ui/floating_point_powi.fixed b/tests/ui/floating_point_powi.fixed index 8ffd4cc51379..41d5288d6e0c 100644 --- a/tests/ui/floating_point_powi.fixed +++ b/tests/ui/floating_point_powi.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/tests/ui/floating_point_powi.rs b/tests/ui/floating_point_powi.rs index 9ae3455a1346..7951aab31beb 100644 --- a/tests/ui/floating_point_powi.rs +++ b/tests/ui/floating_point_powi.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/tests/ui/floating_point_rad.fixed b/tests/ui/floating_point_rad.fixed index 27674b8a455b..af2364527128 100644 --- a/tests/ui/floating_point_rad.fixed +++ b/tests/ui/floating_point_rad.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/tests/ui/floating_point_rad.rs b/tests/ui/floating_point_rad.rs index f1ea73df3984..d7612c56a3e4 100644 --- a/tests/ui/floating_point_rad.rs +++ b/tests/ui/floating_point_rad.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/tests/ui/fn_null_check.rs b/tests/ui/fn_null_check.rs index df5bc8420d57..dfdea100c8fd 100644 --- a/tests/ui/fn_null_check.rs +++ b/tests/ui/fn_null_check.rs @@ -1,6 +1,7 @@ #![allow(unused)] #![warn(clippy::fn_null_check)] #![allow(clippy::cmp_null)] +#![allow(clippy::needless_if)] #![allow(clippy::ptr_eq)] #![allow(clippy::zero_ptr)] diff --git a/tests/ui/fn_null_check.stderr b/tests/ui/fn_null_check.stderr index 660dd3239792..5b9f48a961ca 100644 --- a/tests/ui/fn_null_check.stderr +++ b/tests/ui/fn_null_check.stderr @@ -1,5 +1,5 @@ error: function pointer assumed to be nullable, even though it isn't - --> $DIR/fn_null_check.rs:13:8 + --> $DIR/fn_null_check.rs:14:8 | LL | if (fn_ptr as *mut ()).is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | if (fn_ptr as *mut ()).is_null() {} = note: `-D clippy::fn-null-check` implied by `-D warnings` error: function pointer assumed to be nullable, even though it isn't - --> $DIR/fn_null_check.rs:14:8 + --> $DIR/fn_null_check.rs:15:8 | LL | if (fn_ptr as *const u8).is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | if (fn_ptr as *const u8).is_null() {} = help: try wrapping your function pointer type in `Option` instead, and using `is_none` to check for null pointer value error: function pointer assumed to be nullable, even though it isn't - --> $DIR/fn_null_check.rs:15:8 + --> $DIR/fn_null_check.rs:16:8 | LL | if (fn_ptr as *const ()) == std::ptr::null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | if (fn_ptr as *const ()) == std::ptr::null() {} = help: try wrapping your function pointer type in `Option` instead, and using `is_none` to check for null pointer value error: function pointer assumed to be nullable, even though it isn't - --> $DIR/fn_null_check.rs:16:8 + --> $DIR/fn_null_check.rs:17:8 | LL | if (fn_ptr as *const ()) == (0 as *const ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | if (fn_ptr as *const ()) == (0 as *const ()) {} = help: try wrapping your function pointer type in `Option` instead, and using `is_none` to check for null pointer value error: function pointer assumed to be nullable, even though it isn't - --> $DIR/fn_null_check.rs:17:8 + --> $DIR/fn_null_check.rs:18:8 | LL | if (fn_ptr as *const ()) == ZPTR {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/fn_to_numeric_cast.rs b/tests/ui/fn_to_numeric_cast.rs index a456c085c876..4f6af8708899 100644 --- a/tests/ui/fn_to_numeric_cast.rs +++ b/tests/ui/fn_to_numeric_cast.rs @@ -1,4 +1,4 @@ -// ignore-32bit +//@ignore-32bit #![warn(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)] diff --git a/tests/ui/fn_to_numeric_cast_32bit.rs b/tests/ui/fn_to_numeric_cast_32bit.rs index 04ee985c0863..62ce97f098d4 100644 --- a/tests/ui/fn_to_numeric_cast_32bit.rs +++ b/tests/ui/fn_to_numeric_cast_32bit.rs @@ -1,4 +1,4 @@ -// ignore-64bit +//@ignore-64bit #![warn(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)] diff --git a/tests/ui/fn_to_numeric_cast_32bit.stderr b/tests/ui/fn_to_numeric_cast_32bit.stderr index 08dd611d6752..671347d2bcd5 100644 --- a/tests/ui/fn_to_numeric_cast_32bit.stderr +++ b/tests/ui/fn_to_numeric_cast_32bit.stderr @@ -12,19 +12,19 @@ error: casting function pointer `foo` to `i16`, which truncates the value LL | let _ = foo as i16; | ^^^^^^^^^^ help: try: `foo as usize` -error: casting function pointer `foo` to `i32` +error: casting function pointer `foo` to `i32`, which truncates the value --> $DIR/fn_to_numeric_cast_32bit.rs:12:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ help: try: `foo as usize` - | - = note: `-D clippy::fn-to-numeric-cast` implied by `-D warnings` error: casting function pointer `foo` to `i64` --> $DIR/fn_to_numeric_cast_32bit.rs:13:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ help: try: `foo as usize` + | + = note: `-D clippy::fn-to-numeric-cast` implied by `-D warnings` error: casting function pointer `foo` to `i128` --> $DIR/fn_to_numeric_cast_32bit.rs:14:13 @@ -50,7 +50,7 @@ error: casting function pointer `foo` to `u16`, which truncates the value LL | let _ = foo as u16; | ^^^^^^^^^^ help: try: `foo as usize` -error: casting function pointer `foo` to `u32` +error: casting function pointer `foo` to `u32`, which truncates the value --> $DIR/fn_to_numeric_cast_32bit.rs:19:13 | LL | let _ = foo as u32; @@ -80,7 +80,7 @@ error: casting function pointer `abc` to `i16`, which truncates the value LL | let _ = abc as i16; | ^^^^^^^^^^ help: try: `abc as usize` -error: casting function pointer `abc` to `i32` +error: casting function pointer `abc` to `i32`, which truncates the value --> $DIR/fn_to_numeric_cast_32bit.rs:36:13 | LL | let _ = abc as i32; @@ -116,7 +116,7 @@ error: casting function pointer `abc` to `u16`, which truncates the value LL | let _ = abc as u16; | ^^^^^^^^^^ help: try: `abc as usize` -error: casting function pointer `abc` to `u32` +error: casting function pointer `abc` to `u32`, which truncates the value --> $DIR/fn_to_numeric_cast_32bit.rs:43:13 | LL | let _ = abc as u32; @@ -134,7 +134,7 @@ error: casting function pointer `abc` to `u128` LL | let _ = abc as u128; | ^^^^^^^^^^^ help: try: `abc as usize` -error: casting function pointer `f` to `i32` +error: casting function pointer `f` to `i32`, which truncates the value --> $DIR/fn_to_numeric_cast_32bit.rs:52:5 | LL | f as i32 diff --git a/tests/ui/for_loop_fixable.fixed b/tests/ui/for_loop_fixable.fixed index e9dd38fe40e6..f578c98da153 100644 --- a/tests/ui/for_loop_fixable.fixed +++ b/tests/ui/for_loop_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/for_loop_fixable.rs b/tests/ui/for_loop_fixable.rs index 534fb4dd4ef2..42bc6de0c7dd 100644 --- a/tests/ui/for_loop_fixable.rs +++ b/tests/ui/for_loop_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/for_loop_fixable.stderr b/tests/ui/for_loop_fixable.stderr deleted file mode 100644 index ddfe66d675f9..000000000000 --- a/tests/ui/for_loop_fixable.stderr +++ /dev/null @@ -1,96 +0,0 @@ -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:43:15 - | -LL | for _v in vec.iter() {} - | ^^^^^^^^^^ help: to write this more concisely, try: `&vec` - | - = note: `-D clippy::explicit-iter-loop` implied by `-D warnings` - -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:45:15 - | -LL | for _v in vec.iter_mut() {} - | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut vec` - -error: it is more concise to loop over containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:48:15 - | -LL | for _v in out_vec.into_iter() {} - | ^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `out_vec` - | - = note: `-D clippy::explicit-into-iter-loop` implied by `-D warnings` - -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:53:15 - | -LL | for _v in [1, 2, 3].iter() {} - | ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[1, 2, 3]` - -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:57:15 - | -LL | for _v in [0; 32].iter() {} - | ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 32]` - -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:62:15 - | -LL | for _v in ll.iter() {} - | ^^^^^^^^^ help: to write this more concisely, try: `&ll` - -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:65:15 - | -LL | for _v in vd.iter() {} - | ^^^^^^^^^ help: to write this more concisely, try: `&vd` - -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:68:15 - | -LL | for _v in bh.iter() {} - | ^^^^^^^^^ help: to write this more concisely, try: `&bh` - -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:71:15 - | -LL | for _v in hm.iter() {} - | ^^^^^^^^^ help: to write this more concisely, try: `&hm` - -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:74:15 - | -LL | for _v in bt.iter() {} - | ^^^^^^^^^ help: to write this more concisely, try: `&bt` - -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:77:15 - | -LL | for _v in hs.iter() {} - | ^^^^^^^^^ help: to write this more concisely, try: `&hs` - -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:80:15 - | -LL | for _v in bs.iter() {} - | ^^^^^^^^^ help: to write this more concisely, try: `&bs` - -error: it is more concise to loop over containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:255:18 - | -LL | for i in iterator.into_iter() { - | ^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `iterator` - -error: it is more concise to loop over references to containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:275:18 - | -LL | for _ in t.into_iter() {} - | ^^^^^^^^^^^^^ help: to write this more concisely, try: `&t` - -error: it is more concise to loop over containers instead of using explicit iteration methods - --> $DIR/for_loop_fixable.rs:277:18 - | -LL | for _ in r.into_iter() {} - | ^^^^^^^^^^^^^ help: to write this more concisely, try: `r` - -error: aborting due to 15 previous errors - diff --git a/tests/ui/for_loop_unfixable.rs b/tests/ui/for_loop_unfixable.rs deleted file mode 100644 index 55fb3788a8b1..000000000000 --- a/tests/ui/for_loop_unfixable.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Tests from for_loop.rs that don't have suggestions - -#[warn( - clippy::needless_range_loop, - clippy::explicit_iter_loop, - clippy::explicit_into_iter_loop, - clippy::iter_next_loop, - clippy::for_kv_map -)] -#[allow(clippy::linkedlist, clippy::unnecessary_mut_passed, clippy::similar_names)] -#[allow(for_loops_over_fallibles)] -fn main() { - let vec = vec![1, 2, 3, 4]; - - for _v in vec.iter().next() {} -} diff --git a/tests/ui/for_loop_unfixable.stderr b/tests/ui/for_loop_unfixable.stderr deleted file mode 100644 index 50a86eaa68f7..000000000000 --- a/tests/ui/for_loop_unfixable.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want - --> $DIR/for_loop_unfixable.rs:15:15 - | -LL | for _v in vec.iter().next() {} - | ^^^^^^^^^^^^^^^^^ - | - = note: `-D clippy::iter-next-loop` implied by `-D warnings` - -error: aborting due to previous error - diff --git a/tests/ui/forget_ref.rs b/tests/ui/forget_ref.rs deleted file mode 100644 index 031b415f56ff..000000000000 --- a/tests/ui/forget_ref.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![warn(clippy::forget_ref)] -#![allow(clippy::toplevel_ref_arg)] -#![allow(clippy::unnecessary_wraps, clippy::forget_non_drop)] -#![allow(clippy::borrow_deref_ref)] - -use std::mem::forget; - -struct SomeStruct; - -fn main() { - forget(&SomeStruct); - - let mut owned = SomeStruct; - forget(&owned); - forget(&&owned); - forget(&mut owned); - forget(owned); //OK - - let reference1 = &SomeStruct; - forget(&*reference1); - - let reference2 = &mut SomeStruct; - forget(reference2); - - let ref reference3 = SomeStruct; - forget(reference3); -} - -#[allow(dead_code)] -fn test_generic_fn_forget(val: T) { - forget(&val); - forget(val); //OK -} - -#[allow(dead_code)] -fn test_similarly_named_function() { - fn forget(_val: T) {} - forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name - std::mem::forget(&SomeStruct); -} - -#[derive(Copy, Clone)] -pub struct Error; -fn produce_half_owl_error() -> Result<(), Error> { - Ok(()) -} - -fn produce_half_owl_ok() -> Result { - Ok(true) -} diff --git a/tests/ui/forget_ref.stderr b/tests/ui/forget_ref.stderr deleted file mode 100644 index 011cdefc665f..000000000000 --- a/tests/ui/forget_ref.stderr +++ /dev/null @@ -1,111 +0,0 @@ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:11:5 - | -LL | forget(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:11:12 - | -LL | forget(&SomeStruct); - | ^^^^^^^^^^^ - = note: `-D clippy::forget-ref` implied by `-D warnings` - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:14:5 - | -LL | forget(&owned); - | ^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:14:12 - | -LL | forget(&owned); - | ^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:15:5 - | -LL | forget(&&owned); - | ^^^^^^^^^^^^^^^ - | -note: argument has type `&&SomeStruct` - --> $DIR/forget_ref.rs:15:12 - | -LL | forget(&&owned); - | ^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:16:5 - | -LL | forget(&mut owned); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/forget_ref.rs:16:12 - | -LL | forget(&mut owned); - | ^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:20:5 - | -LL | forget(&*reference1); - | ^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:20:12 - | -LL | forget(&*reference1); - | ^^^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:23:5 - | -LL | forget(reference2); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/forget_ref.rs:23:12 - | -LL | forget(reference2); - | ^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:26:5 - | -LL | forget(reference3); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:26:12 - | -LL | forget(reference3); - | ^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:31:5 - | -LL | forget(&val); - | ^^^^^^^^^^^^ - | -note: argument has type `&T` - --> $DIR/forget_ref.rs:31:12 - | -LL | forget(&val); - | ^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:39:5 - | -LL | std::mem::forget(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:39:22 - | -LL | std::mem::forget(&SomeStruct); - | ^^^^^^^^^^^ - -error: aborting due to 9 previous errors - diff --git a/tests/ui/format.fixed b/tests/ui/format.fixed index beedf2c1db29..0c2ad4e64e4c 100644 --- a/tests/ui/format.fixed +++ b/tests/ui/format.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::useless_format)] #![allow( unused_tuple_struct_fields, @@ -6,7 +6,16 @@ clippy::redundant_clone, clippy::to_string_in_format_args, clippy::needless_borrow, - clippy::uninlined_format_args + clippy::uninlined_format_args, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::needless_raw_string_hashes, +======= +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + clippy::needless_raw_string_hashes, +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) + clippy::useless_vec )] struct Foo(pub String); diff --git a/tests/ui/format.rs b/tests/ui/format.rs index e805f1818898..1ca51eaaf2e8 100644 --- a/tests/ui/format.rs +++ b/tests/ui/format.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::useless_format)] #![allow( unused_tuple_struct_fields, @@ -6,7 +6,16 @@ clippy::redundant_clone, clippy::to_string_in_format_args, clippy::needless_borrow, - clippy::uninlined_format_args + clippy::uninlined_format_args, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::needless_raw_string_hashes, +======= +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + clippy::needless_raw_string_hashes, +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) + clippy::useless_vec )] struct Foo(pub String); diff --git a/tests/ui/format.stderr b/tests/ui/format.stderr index 0ef0ac655d39..84495a265845 100644 --- a/tests/ui/format.stderr +++ b/tests/ui/format.stderr @@ -1,5 +1,13 @@ error: useless use of `format!` - --> $DIR/format.rs:19:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:21:5 +======= + --> $DIR/format.rs:20:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:21:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | format!("foo"); | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` @@ -7,19 +15,43 @@ LL | format!("foo"); = note: `-D clippy::useless-format` implied by `-D warnings` error: useless use of `format!` - --> $DIR/format.rs:20:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:22:5 +======= + --> $DIR/format.rs:21:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:22:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | format!("{{}}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()` error: useless use of `format!` - --> $DIR/format.rs:21:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:23:5 +======= + --> $DIR/format.rs:22:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:23:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | format!("{{}} abc {{}}"); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()` error: useless use of `format!` - --> $DIR/format.rs:22:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:24:5 +======= + --> $DIR/format.rs:23:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:24:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | / format!( LL | | r##"foo {{}} @@ -34,67 +66,155 @@ LL ~ " bar"##.to_string(); | error: useless use of `format!` - --> $DIR/format.rs:27:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:29:13 +======= + --> $DIR/format.rs:28:13 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:29:13 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let _ = format!(""); | ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()` error: useless use of `format!` - --> $DIR/format.rs:29:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:31:5 +======= + --> $DIR/format.rs:30:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:31:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | format!("{}", "foo"); | ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` error: useless use of `format!` - --> $DIR/format.rs:37:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:39:5 +======= + --> $DIR/format.rs:38:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:39:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | format!("{}", arg); | ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()` error: useless use of `format!` - --> $DIR/format.rs:67:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:69:5 +======= + --> $DIR/format.rs:68:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:69:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | format!("{}", 42.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()` error: useless use of `format!` - --> $DIR/format.rs:69:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:71:5 +======= + --> $DIR/format.rs:70:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:71:5 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | format!("{}", x.display().to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()` error: useless use of `format!` - --> $DIR/format.rs:73:18 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:75:18 +======= + --> $DIR/format.rs:74:18 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:75:18 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let _ = Some(format!("{}", a + "bar")); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"` error: useless use of `format!` - --> $DIR/format.rs:77:22 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:79:22 +======= + --> $DIR/format.rs:78:22 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:79:22 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let _s: String = format!("{}", &*v.join("/n")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()` error: useless use of `format!` - --> $DIR/format.rs:83:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:85:13 +======= + --> $DIR/format.rs:84:13 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:85:13 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let _ = format!("{x}"); | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> $DIR/format.rs:85:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:87:13 +======= + --> $DIR/format.rs:86:13 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:87:13 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let _ = format!("{y}", y = x); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> $DIR/format.rs:89:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:91:13 +======= + --> $DIR/format.rs:90:13 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:91:13 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let _ = format!("{abc}"); | ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()` error: useless use of `format!` - --> $DIR/format.rs:91:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/format.rs:93:13 +======= + --> $DIR/format.rs:92:13 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/format.rs:93:13 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let _ = format!("{xx}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()` diff --git a/tests/ui/format_args.fixed b/tests/ui/format_args.fixed index 825e122be5a5..ea3836861357 100644 --- a/tests/ui/format_args.fixed +++ b/tests/ui/format_args.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::to_string_in_format_args)] #![allow(unused)] #![allow( diff --git a/tests/ui/format_args.rs b/tests/ui/format_args.rs index a41e53389e52..bfb324492467 100644 --- a/tests/ui/format_args.rs +++ b/tests/ui/format_args.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::to_string_in_format_args)] #![allow(unused)] #![allow( diff --git a/tests/ui/format_push_string.rs b/tests/ui/format_push_string.rs index 4db13d650eb1..89423ffe1cf8 100644 --- a/tests/ui/format_push_string.rs +++ b/tests/ui/format_push_string.rs @@ -5,3 +5,32 @@ fn main() { string += &format!("{:?}", 1234); string.push_str(&format!("{:?}", 5678)); } + +mod issue9493 { + pub fn u8vec_to_hex(vector: &Vec, upper: bool) -> String { + let mut hex = String::with_capacity(vector.len() * 2); + for byte in vector { + hex += &(if upper { + format!("{byte:02X}") + } else { + format!("{byte:02x}") + }); + } + hex + } + + pub fn other_cases() { + let mut s = String::new(); + // if let + s += &(if let Some(_a) = Some(1234) { + format!("{}", 1234) + } else { + format!("{}", 1234) + }); + // match + s += &(match Some(1234) { + Some(_) => format!("{}", 1234), + None => format!("{}", 1234), + }); + } +} diff --git a/tests/ui/format_push_string.stderr b/tests/ui/format_push_string.stderr index d7be9a5f206c..76762c4a1d1f 100644 --- a/tests/ui/format_push_string.stderr +++ b/tests/ui/format_push_string.stderr @@ -15,5 +15,40 @@ LL | string.push_str(&format!("{:?}", 5678)); | = help: consider using `write!` to avoid the extra allocation -error: aborting due to 2 previous errors +error: `format!(..)` appended to existing `String` + --> $DIR/format_push_string.rs:13:13 + | +LL | / hex += &(if upper { +LL | | format!("{byte:02X}") +LL | | } else { +LL | | format!("{byte:02x}") +LL | | }); + | |______________^ + | + = help: consider using `write!` to avoid the extra allocation + +error: `format!(..)` appended to existing `String` + --> $DIR/format_push_string.rs:25:9 + | +LL | / s += &(if let Some(_a) = Some(1234) { +LL | | format!("{}", 1234) +LL | | } else { +LL | | format!("{}", 1234) +LL | | }); + | |__________^ + | + = help: consider using `write!` to avoid the extra allocation + +error: `format!(..)` appended to existing `String` + --> $DIR/format_push_string.rs:31:9 + | +LL | / s += &(match Some(1234) { +LL | | Some(_) => format!("{}", 1234), +LL | | None => format!("{}", 1234), +LL | | }); + | |__________^ + | + = help: consider using `write!` to avoid the extra allocation + +error: aborting due to 5 previous errors diff --git a/tests/ui/from_iter_instead_of_collect.fixed b/tests/ui/from_iter_instead_of_collect.fixed index 48f8093311cb..1671987cb673 100644 --- a/tests/ui/from_iter_instead_of_collect.fixed +++ b/tests/ui/from_iter_instead_of_collect.fixed @@ -1,7 +1,8 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::from_iter_instead_of_collect)] #![allow(unused_imports, unused_tuple_struct_fields)] +#![allow(clippy::useless_vec)] use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque}; diff --git a/tests/ui/from_iter_instead_of_collect.rs b/tests/ui/from_iter_instead_of_collect.rs index ebe0ad278be3..48509b32f109 100644 --- a/tests/ui/from_iter_instead_of_collect.rs +++ b/tests/ui/from_iter_instead_of_collect.rs @@ -1,7 +1,8 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::from_iter_instead_of_collect)] #![allow(unused_imports, unused_tuple_struct_fields)] +#![allow(clippy::useless_vec)] use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque}; diff --git a/tests/ui/from_iter_instead_of_collect.stderr b/tests/ui/from_iter_instead_of_collect.stderr index 8aa3c3c01f81..8f08ac8c3ff4 100644 --- a/tests/ui/from_iter_instead_of_collect.stderr +++ b/tests/ui/from_iter_instead_of_collect.stderr @@ -1,5 +1,5 @@ error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:18:9 + --> $DIR/from_iter_instead_of_collect.rs:19:9 | LL | >::from_iter(iter.into_iter().copied()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.into_iter().copied().collect::()` @@ -7,85 +7,85 @@ LL | >::from_iter(iter.into_iter().copied()) = note: `-D clippy::from-iter-instead-of-collect` implied by `-D warnings` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:24:13 + --> $DIR/from_iter_instead_of_collect.rs:25:13 | LL | let _ = Vec::from_iter(iter_expr); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter_expr.collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:26:13 + --> $DIR/from_iter_instead_of_collect.rs:27:13 | LL | let _ = HashMap::::from_iter(vec![5, 5, 5, 5].iter().enumerate()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `vec![5, 5, 5, 5].iter().enumerate().collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:31:19 + --> $DIR/from_iter_instead_of_collect.rs:32:19 | LL | assert_eq!(a, Vec::from_iter(0..3)); | ^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:32:19 + --> $DIR/from_iter_instead_of_collect.rs:33:19 | LL | assert_eq!(a, Vec::::from_iter(0..3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:34:17 + --> $DIR/from_iter_instead_of_collect.rs:35:17 | LL | let mut b = VecDeque::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:37:17 + --> $DIR/from_iter_instead_of_collect.rs:38:17 | LL | let mut b = VecDeque::::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:42:21 + --> $DIR/from_iter_instead_of_collect.rs:43:21 | LL | let mut b = collections::VecDeque::::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:47:14 + --> $DIR/from_iter_instead_of_collect.rs:48:14 | LL | let bm = BTreeMap::from_iter(values.iter().cloned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `values.iter().cloned().collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:48:19 + --> $DIR/from_iter_instead_of_collect.rs:49:19 | LL | let mut bar = BTreeMap::from_iter(bm.range(0..2)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `bm.range(0..2).collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:51:19 + --> $DIR/from_iter_instead_of_collect.rs:52:19 | LL | let mut bts = BTreeSet::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:55:17 + --> $DIR/from_iter_instead_of_collect.rs:56:17 | LL | let _ = collections::BTreeSet::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:56:17 + --> $DIR/from_iter_instead_of_collect.rs:57:17 | LL | let _ = collections::BTreeSet::::from_iter(0..3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:59:15 + --> $DIR/from_iter_instead_of_collect.rs:60:15 | LL | for _i in Vec::from_iter([1, 2, 3].iter()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::>()` error: usage of `FromIterator::from_iter` - --> $DIR/from_iter_instead_of_collect.rs:60:15 + --> $DIR/from_iter_instead_of_collect.rs:61:15 | LL | for _i in Vec::<&i32>::from_iter([1, 2, 3].iter()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::>()` diff --git a/tests/ui/from_over_into.fixed b/tests/ui/from_over_into.fixed index 72d635c2ccd6..1f6dfa5fda71 100644 --- a/tests/ui/from_over_into.fixed +++ b/tests/ui/from_over_into.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(type_alias_impl_trait)] #![warn(clippy::from_over_into)] @@ -32,7 +32,7 @@ struct SelfKeywords; impl From for SelfKeywords { fn from(val: X) -> Self { - let _ = X::default(); + let _ = X; let _ = X::FOO; let _: X = val; @@ -60,6 +60,15 @@ impl From for A { } } +struct PathInExpansion; + +impl From for String { + fn from(val: PathInExpansion) -> Self { + // non self/Self paths in expansions are fine + panic!() + } +} + #[clippy::msrv = "1.40"] fn msrv_1_40() { struct FromOverInto(Vec); @@ -82,10 +91,26 @@ fn msrv_1_41() { } } +<<<<<<< HEAD +======= type Opaque = impl Sized; struct IntoOpaque; impl Into for IntoOpaque { fn into(self) -> Opaque {} } +<<<<<<< HEAD +pub struct Lval(T); + +pub struct Rval(T); + +impl Into> for Lval { + fn into(self) -> Rval { + Rval(self) + } +} + +>>>>>>> d4b388eb4 (Add from_over_into replace for type in `Self` reference) +======= +>>>>>>> b2c85b31b (Move bail into lint to prevent no-linting, move to unfixable) fn main() {} diff --git a/tests/ui/from_over_into.rs b/tests/ui/from_over_into.rs index 965f4d5d7859..c0c5f9fe3c09 100644 --- a/tests/ui/from_over_into.rs +++ b/tests/ui/from_over_into.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(type_alias_impl_trait)] #![warn(clippy::from_over_into)] @@ -32,7 +32,7 @@ struct SelfKeywords; impl Into for X { fn into(self) -> SelfKeywords { - let _ = Self::default(); + let _ = Self; let _ = Self::FOO; let _: Self = self; @@ -60,6 +60,15 @@ impl From for A { } } +struct PathInExpansion; + +impl Into for PathInExpansion { + fn into(self) -> String { + // non self/Self paths in expansions are fine + panic!() + } +} + #[clippy::msrv = "1.40"] fn msrv_1_40() { struct FromOverInto(Vec); @@ -82,10 +91,26 @@ fn msrv_1_41() { } } +<<<<<<< HEAD +======= type Opaque = impl Sized; struct IntoOpaque; impl Into for IntoOpaque { fn into(self) -> Opaque {} } +<<<<<<< HEAD +pub struct Lval(T); + +pub struct Rval(T); + +impl Into> for Lval { + fn into(self) -> Rval { + Rval(self) + } +} + +>>>>>>> d4b388eb4 (Add from_over_into replace for type in `Self` reference) +======= +>>>>>>> b2c85b31b (Move bail into lint to prevent no-linting, move to unfixable) fn main() {} diff --git a/tests/ui/from_over_into.stderr b/tests/ui/from_over_into.stderr index 3c4d011d6fb4..3c9f9934efe3 100644 --- a/tests/ui/from_over_into.stderr +++ b/tests/ui/from_over_into.stderr @@ -5,7 +5,7 @@ LL | impl Into for String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::from-over-into` implied by `-D warnings` -help: replace the `Into` implentation with `From` +help: replace the `Into` implementation with `From` | LL ~ impl From for StringWrapper { LL ~ fn from(val: String) -> Self { @@ -18,7 +18,7 @@ error: an implementation of `From` is preferred since it gives you `Into<_>` for LL | impl Into for String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace the `Into` implentation with `From` +help: replace the `Into` implementation with `From` | LL ~ impl From for SelfType { LL ~ fn from(val: String) -> Self { @@ -31,11 +31,11 @@ error: an implementation of `From` is preferred since it gives you `Into<_>` for LL | impl Into for X { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace the `Into` implentation with `From` +help: replace the `Into` implementation with `From` | LL ~ impl From for SelfKeywords { LL ~ fn from(val: X) -> Self { -LL ~ let _ = X::default(); +LL ~ let _ = X; LL ~ let _ = X::FOO; LL ~ let _: X = val; | @@ -48,7 +48,7 @@ LL | impl core::convert::Into for crate::ExplicitPaths { | = help: `impl From for Foreign` is allowed by the orphan rules, for more information see https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence -help: replace the `Into` implentation with `From` +help: replace the `Into` implementation with `From` | LL ~ impl core::convert::From for bool { LL ~ fn from(mut val: crate::ExplicitPaths) -> Self { @@ -59,17 +59,55 @@ LL ~ val.0 | error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true - --> $DIR/from_over_into.rs:78:5 + --> $DIR/from_over_into.rs:65:1 + | +LL | impl Into for PathInExpansion { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `impl From for Foreign` is allowed by the orphan rules, for more information see + https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence +help: replace the `Into` implementation with `From` + | +LL ~ impl From for String { +LL ~ fn from(val: PathInExpansion) -> Self { + | + +error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true + --> $DIR/from_over_into.rs:87:5 | LL | impl Into> for Vec { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: replace the `Into` implentation with `From>` +help: replace the `Into` implementation with `From>` | LL ~ impl From> for FromOverInto { LL ~ fn from(val: Vec) -> Self { LL ~ FromOverInto(val) | +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true + --> $DIR/from_over_into.rs:95:1 + | +LL | impl Into> for Lval { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace the `Into` implementation with `From>` + | +LL ~ impl From> for Rval> { +LL ~ fn from(val: Lval) -> Self { +LL ~ Rval(val) + | + +>>>>>>> d4b388eb4 (Add from_over_into replace for type in `Self` reference) +error: aborting due to 6 previous errors +======= error: aborting due to 5 previous errors +>>>>>>> 16f1cf8fd (Ignore from_over_into if it contains Self) +======= +error: aborting due to 6 previous errors +>>>>>>> c10876e6c (from_over_into: Show suggestions for non-Self expanded paths) diff --git a/tests/ui/from_over_into_unfixable.rs b/tests/ui/from_over_into_unfixable.rs index 3b280b7488ae..c769e38eb33a 100644 --- a/tests/ui/from_over_into_unfixable.rs +++ b/tests/ui/from_over_into_unfixable.rs @@ -3,14 +3,14 @@ struct InMacro(String); macro_rules! in_macro { - ($e:ident) => { - $e + () => { + Self::new() }; } impl Into for String { fn into(self) -> InMacro { - InMacro(in_macro!(self)) + InMacro(in_macro!()) } } @@ -32,4 +32,14 @@ impl Into for ContainsVal { } } +pub struct Lval(T); + +pub struct Rval(T); + +impl Into> for Lval { + fn into(self) -> Rval { + Rval(self) + } +} + fn main() {} diff --git a/tests/ui/from_over_into_unfixable.stderr b/tests/ui/from_over_into_unfixable.stderr index 6f6ce351921b..2ab9b9d6b17c 100644 --- a/tests/ui/from_over_into_unfixable.stderr +++ b/tests/ui/from_over_into_unfixable.stderr @@ -4,7 +4,7 @@ error: an implementation of `From` is preferred since it gives you `Into<_>` for LL | impl Into for String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: replace the `Into` implentation with `From` + = help: replace the `Into` implementation with `From` = note: `-D clippy::from-over-into` implied by `-D warnings` error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true @@ -13,7 +13,7 @@ error: an implementation of `From` is preferred since it gives you `Into<_>` for LL | impl Into for &'static [u8] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: replace the `Into` implentation with `From<&'static [u8]>` + = help: replace the `Into` implementation with `From<&'static [u8]>` error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true --> $DIR/from_over_into_unfixable.rs:28:1 @@ -23,7 +23,15 @@ LL | impl Into for ContainsVal { | = help: `impl From for Foreign` is allowed by the orphan rules, for more information see https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence - = help: replace the `Into` implentation with `From` + = help: replace the `Into` implementation with `From` -error: aborting due to 3 previous errors +error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true + --> $DIR/from_over_into_unfixable.rs:39:1 + | +LL | impl Into> for Lval { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: replace the `Into` implementation with `From>` + +error: aborting due to 4 previous errors diff --git a/tests/ui/from_raw_with_void_ptr.rs b/tests/ui/from_raw_with_void_ptr.rs index 8484da2415ab..95ef6425fad9 100644 --- a/tests/ui/from_raw_with_void_ptr.rs +++ b/tests/ui/from_raw_with_void_ptr.rs @@ -1,4 +1,5 @@ #![warn(clippy::from_raw_with_void_ptr)] +#![allow(clippy::unnecessary_cast)] use std::ffi::c_void; use std::rc::Rc; diff --git a/tests/ui/from_raw_with_void_ptr.stderr b/tests/ui/from_raw_with_void_ptr.stderr index 96e4af12ba38..1963d08014b1 100644 --- a/tests/ui/from_raw_with_void_ptr.stderr +++ b/tests/ui/from_raw_with_void_ptr.stderr @@ -1,60 +1,60 @@ error: creating a `Box` from a void raw pointer - --> $DIR/from_raw_with_void_ptr.rs:10:22 + --> $DIR/from_raw_with_void_ptr.rs:11:22 | LL | let _ = unsafe { Box::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> $DIR/from_raw_with_void_ptr.rs:10:36 + --> $DIR/from_raw_with_void_ptr.rs:11:36 | LL | let _ = unsafe { Box::from_raw(ptr) }; | ^^^ = note: `-D clippy::from-raw-with-void-ptr` implied by `-D warnings` error: creating a `Rc` from a void raw pointer - --> $DIR/from_raw_with_void_ptr.rs:21:22 + --> $DIR/from_raw_with_void_ptr.rs:22:22 | LL | let _ = unsafe { Rc::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> $DIR/from_raw_with_void_ptr.rs:21:35 + --> $DIR/from_raw_with_void_ptr.rs:22:35 | LL | let _ = unsafe { Rc::from_raw(ptr) }; | ^^^ error: creating a `Arc` from a void raw pointer - --> $DIR/from_raw_with_void_ptr.rs:25:22 + --> $DIR/from_raw_with_void_ptr.rs:26:22 | LL | let _ = unsafe { Arc::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> $DIR/from_raw_with_void_ptr.rs:25:36 + --> $DIR/from_raw_with_void_ptr.rs:26:36 | LL | let _ = unsafe { Arc::from_raw(ptr) }; | ^^^ error: creating a `Weak` from a void raw pointer - --> $DIR/from_raw_with_void_ptr.rs:29:22 + --> $DIR/from_raw_with_void_ptr.rs:30:22 | LL | let _ = unsafe { std::rc::Weak::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> $DIR/from_raw_with_void_ptr.rs:29:46 + --> $DIR/from_raw_with_void_ptr.rs:30:46 | LL | let _ = unsafe { std::rc::Weak::from_raw(ptr) }; | ^^^ error: creating a `Weak` from a void raw pointer - --> $DIR/from_raw_with_void_ptr.rs:33:22 + --> $DIR/from_raw_with_void_ptr.rs:34:22 | LL | let _ = unsafe { std::sync::Weak::from_raw(ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: cast this to a pointer of the appropriate type - --> $DIR/from_raw_with_void_ptr.rs:33:48 + --> $DIR/from_raw_with_void_ptr.rs:34:48 | LL | let _ = unsafe { std::sync::Weak::from_raw(ptr) }; | ^^^ diff --git a/tests/ui/future_not_send.stderr b/tests/ui/future_not_send.stderr index 5b6858e4568b..5c6348962a5e 100644 --- a/tests/ui/future_not_send.stderr +++ b/tests/ui/future_not_send.stderr @@ -5,22 +5,22 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { | ^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> $DIR/future_not_send.rs:8:19 + --> $DIR/future_not_send.rs:8:20 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { | -- has type `std::rc::Rc<[u8]>` which is not `Send` LL | async { true }.await - | ^^^^^^ await occurs here, with `rc` maybe used later + | ^^^^^ await occurs here, with `rc` maybe used later LL | } | - `rc` is later dropped here = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` note: future is not `Send` as this value is used across an await - --> $DIR/future_not_send.rs:8:19 + --> $DIR/future_not_send.rs:8:20 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { | ---- has type `&std::cell::Cell` which is not `Send` LL | async { true }.await - | ^^^^^^ await occurs here, with `cell` maybe used later + | ^^^^^ await occurs here, with `cell` maybe used later LL | } | - `cell` is later dropped here = note: `std::cell::Cell` doesn't implement `std::marker::Sync` @@ -33,12 +33,12 @@ LL | pub async fn public_future(rc: Rc<[u8]>) { | ^ future returned by `public_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> $DIR/future_not_send.rs:12:19 + --> $DIR/future_not_send.rs:12:20 | LL | pub async fn public_future(rc: Rc<[u8]>) { | -- has type `std::rc::Rc<[u8]>` which is not `Send` LL | async { true }.await; - | ^^^^^^ await occurs here, with `rc` maybe used later + | ^^^^^ await occurs here, with `rc` maybe used later LL | } | - `rc` is later dropped here = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` @@ -82,12 +82,12 @@ LL | async fn private_future(&self) -> usize { | ^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> $DIR/future_not_send.rs:35:23 + --> $DIR/future_not_send.rs:35:24 | LL | async fn private_future(&self) -> usize { | ----- has type `&Dummy` which is not `Send` LL | async { true }.await; - | ^^^^^^ await occurs here, with `&self` maybe used later + | ^^^^^ await occurs here, with `&self` maybe used later LL | self.rc.len() LL | } | - `&self` is later dropped here @@ -100,12 +100,12 @@ LL | pub async fn public_future(&self) { | ^ future returned by `public_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> $DIR/future_not_send.rs:40:30 + --> $DIR/future_not_send.rs:40:31 | LL | pub async fn public_future(&self) { | ----- has type `&Dummy` which is not `Send` LL | self.private_future().await; - | ^^^^^^ await occurs here, with `&self` maybe used later + | ^^^^^ await occurs here, with `&self` maybe used later LL | } | - `&self` is later dropped here = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` @@ -117,12 +117,12 @@ LL | async fn generic_future(t: T) -> T | ^ future returned by `generic_future` is not `Send` | note: future is not `Send` as this value is used across an await - --> $DIR/future_not_send.rs:54:19 + --> $DIR/future_not_send.rs:54:20 | LL | let rt = &t; | -- has type `&T` which is not `Send` LL | async { true }.await; - | ^^^^^^ await occurs here, with `rt` maybe used later + | ^^^^^ await occurs here, with `rt` maybe used later LL | t LL | } | - `rt` is later dropped here diff --git a/tests/ui/get_first.fixed b/tests/ui/get_first.fixed index def58afa4fbf..bc2f86566bc0 100644 --- a/tests/ui/get_first.fixed +++ b/tests/ui/get_first.fixed @@ -1,8 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::get_first)] -use std::collections::BTreeMap; -use std::collections::HashMap; -use std::collections::VecDeque; +#![allow(clippy::useless_vec)] +use std::collections::{BTreeMap, HashMap, VecDeque}; struct Bar { arr: [u32; 3], diff --git a/tests/ui/get_first.rs b/tests/ui/get_first.rs index 85a381854cd3..bc0e233fdee5 100644 --- a/tests/ui/get_first.rs +++ b/tests/ui/get_first.rs @@ -1,8 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::get_first)] -use std::collections::BTreeMap; -use std::collections::HashMap; -use std::collections::VecDeque; +#![allow(clippy::useless_vec)] +use std::collections::{BTreeMap, HashMap, VecDeque}; struct Bar { arr: [u32; 3], diff --git a/tests/ui/get_first.stderr b/tests/ui/get_first.stderr index 466beff9c92d..0899a5905f30 100644 --- a/tests/ui/get_first.stderr +++ b/tests/ui/get_first.stderr @@ -1,5 +1,5 @@ error: accessing first element with `x.get(0)` - --> $DIR/get_first.rs:19:13 + --> $DIR/get_first.rs:18:13 | LL | let _ = x.get(0); // Use x.first() | ^^^^^^^^ help: try: `x.first()` @@ -7,13 +7,13 @@ LL | let _ = x.get(0); // Use x.first() = note: `-D clippy::get-first` implied by `-D warnings` error: accessing first element with `y.get(0)` - --> $DIR/get_first.rs:24:13 + --> $DIR/get_first.rs:23:13 | LL | let _ = y.get(0); // Use y.first() | ^^^^^^^^ help: try: `y.first()` error: accessing first element with `z.get(0)` - --> $DIR/get_first.rs:29:13 + --> $DIR/get_first.rs:28:13 | LL | let _ = z.get(0); // Use z.first() | ^^^^^^^^ help: try: `z.first()` diff --git a/tests/ui/get_last_with_len.fixed b/tests/ui/get_last_with_len.fixed index 1e90b37687a1..01a83e5bf343 100644 --- a/tests/ui/get_last_with_len.fixed +++ b/tests/ui/get_last_with_len.fixed @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::get_last_with_len)] -#![allow(unused)] +#![allow(unused, clippy::useless_vec)] use std::collections::VecDeque; diff --git a/tests/ui/get_last_with_len.rs b/tests/ui/get_last_with_len.rs index d63a731bd524..d82484b46d3f 100644 --- a/tests/ui/get_last_with_len.rs +++ b/tests/ui/get_last_with_len.rs @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::get_last_with_len)] -#![allow(unused)] +#![allow(unused, clippy::useless_vec)] use std::collections::VecDeque; diff --git a/tests/ui/get_unwrap.fixed b/tests/ui/get_unwrap.fixed index 5827fc7d76e6..c972edf7df19 100644 --- a/tests/ui/get_unwrap.fixed +++ b/tests/ui/get_unwrap.fixed @@ -1,12 +1,15 @@ -// run-rustfix +//@run-rustfix -#![allow(unused_mut, clippy::from_iter_instead_of_collect, clippy::get_first)] +#![allow( + unused_mut, + clippy::from_iter_instead_of_collect, + clippy::get_first, + clippy::useless_vec +)] #![warn(clippy::unwrap_used)] #![deny(clippy::get_unwrap)] -use std::collections::BTreeMap; -use std::collections::HashMap; -use std::collections::VecDeque; +use std::collections::{BTreeMap, HashMap, VecDeque}; struct GetFalsePositive { arr: [u32; 3], @@ -65,3 +68,81 @@ fn main() { let _ = some_vec[0..1].to_vec(); } } +mod issue9909 { + #![allow(clippy::identity_op, clippy::unwrap_used, dead_code)] + + fn reduced() { + let f = &[1, 2, 3]; + + // include a borrow in the suggestion, even if the argument is not just a numeric literal + let _x: &i32 = &f[1 + 2]; + + // don't include a borrow here + let _x = f[1 + 2].to_string(); + + // don't include a borrow here + let _x = f[1 + 2].abs(); + } + + // original code: + fn linidx(row: usize, col: usize) -> usize { + row * 1 + col * 3 + } + + fn main_() { + let mut mat = [1.0f32, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0]; + + for i in 0..2 { + for j in i + 1..3 { + if mat[linidx(j, 3)] > mat[linidx(i, 3)] { + for k in 0..4 { + let (x, rest) = mat.split_at_mut(linidx(i, k) + 1); + let a = x.last_mut().unwrap(); + let b = &mut rest[linidx(j, k) - linidx(i, k) - 1]; + ::std::mem::swap(a, b); + } + } + } + } + assert_eq!([9.0, 5.0, 1.0, 10.0, 6.0, 2.0, 11.0, 7.0, 3.0, 12.0, 8.0, 4.0], mat); + } +} +mod issue9909 { + #![allow(clippy::identity_op, clippy::unwrap_used, dead_code)] + + fn reduced() { + let f = &[1, 2, 3]; + + // include a borrow in the suggestion, even if the argument is not just a numeric literal + let _x: &i32 = &f[1 + 2]; + + // don't include a borrow here + let _x = f[1 + 2].to_string(); + + // don't include a borrow here + let _x = f[1 + 2].abs(); + } + + // original code: + fn linidx(row: usize, col: usize) -> usize { + row * 1 + col * 3 + } + + fn main_() { + let mut mat = [1.0f32, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0]; + + for i in 0..2 { + for j in i + 1..3 { + if mat[linidx(j, 3)] > mat[linidx(i, 3)] { + for k in 0..4 { + let (x, rest) = mat.split_at_mut(linidx(i, k) + 1); + let a = x.last_mut().unwrap(); + let b = &mut rest[linidx(j, k) - linidx(i, k) - 1]; + ::std::mem::swap(a, b); + } + } + } + } + assert_eq!([9.0, 5.0, 1.0, 10.0, 6.0, 2.0, 11.0, 7.0, 3.0, 12.0, 8.0, 4.0], mat); + } +} diff --git a/tests/ui/get_unwrap.rs b/tests/ui/get_unwrap.rs index a2a323c14fb7..1d124d299d67 100644 --- a/tests/ui/get_unwrap.rs +++ b/tests/ui/get_unwrap.rs @@ -1,12 +1,15 @@ -// run-rustfix +//@run-rustfix -#![allow(unused_mut, clippy::from_iter_instead_of_collect, clippy::get_first)] +#![allow( + unused_mut, + clippy::from_iter_instead_of_collect, + clippy::get_first, + clippy::useless_vec +)] #![warn(clippy::unwrap_used)] #![deny(clippy::get_unwrap)] -use std::collections::BTreeMap; -use std::collections::HashMap; -use std::collections::VecDeque; +use std::collections::{BTreeMap, HashMap, VecDeque}; struct GetFalsePositive { arr: [u32; 3], @@ -65,3 +68,81 @@ fn main() { let _ = some_vec.get_mut(0..1).unwrap().to_vec(); } } +mod issue9909 { + #![allow(clippy::identity_op, clippy::unwrap_used, dead_code)] + + fn reduced() { + let f = &[1, 2, 3]; + + // include a borrow in the suggestion, even if the argument is not just a numeric literal + let _x: &i32 = f.get(1 + 2).unwrap(); + + // don't include a borrow here + let _x = f.get(1 + 2).unwrap().to_string(); + + // don't include a borrow here + let _x = f.get(1 + 2).unwrap().abs(); + } + + // original code: + fn linidx(row: usize, col: usize) -> usize { + row * 1 + col * 3 + } + + fn main_() { + let mut mat = [1.0f32, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0]; + + for i in 0..2 { + for j in i + 1..3 { + if mat[linidx(j, 3)] > mat[linidx(i, 3)] { + for k in 0..4 { + let (x, rest) = mat.split_at_mut(linidx(i, k) + 1); + let a = x.last_mut().unwrap(); + let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap(); + ::std::mem::swap(a, b); + } + } + } + } + assert_eq!([9.0, 5.0, 1.0, 10.0, 6.0, 2.0, 11.0, 7.0, 3.0, 12.0, 8.0, 4.0], mat); + } +} +mod issue9909 { + #![allow(clippy::identity_op, clippy::unwrap_used, dead_code)] + + fn reduced() { + let f = &[1, 2, 3]; + + // include a borrow in the suggestion, even if the argument is not just a numeric literal + let _x: &i32 = f.get(1 + 2).unwrap(); + + // don't include a borrow here + let _x = f.get(1 + 2).unwrap().to_string(); + + // don't include a borrow here + let _x = f.get(1 + 2).unwrap().abs(); + } + + // original code: + fn linidx(row: usize, col: usize) -> usize { + row * 1 + col * 3 + } + + fn main_() { + let mut mat = [1.0f32, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0]; + + for i in 0..2 { + for j in i + 1..3 { + if mat[linidx(j, 3)] > mat[linidx(i, 3)] { + for k in 0..4 { + let (x, rest) = mat.split_at_mut(linidx(i, k) + 1); + let a = x.last_mut().unwrap(); + let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap(); + ::std::mem::swap(a, b); + } + } + } + } + assert_eq!([9.0, 5.0, 1.0, 10.0, 6.0, 2.0, 11.0, 7.0, 3.0, 12.0, 8.0, 4.0], mat); + } +} diff --git a/tests/ui/get_unwrap.stderr b/tests/ui/get_unwrap.stderr index 6dee4d5b4b62..ebf8b849a14a 100644 --- a/tests/ui/get_unwrap.stderr +++ b/tests/ui/get_unwrap.stderr @@ -1,17 +1,17 @@ error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:35:17 + --> $DIR/get_unwrap.rs:38:17 | LL | let _ = boxed_slice.get(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&boxed_slice[1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&boxed_slice[1]` | note: the lint level is defined here - --> $DIR/get_unwrap.rs:5:9 + --> $DIR/get_unwrap.rs:10:9 | LL | #![deny(clippy::get_unwrap)] | ^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:35:17 + --> $DIR/get_unwrap.rs:38:17 | LL | let _ = boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,13 +20,13 @@ LL | let _ = boxed_slice.get(1).unwrap(); = note: `-D clippy::unwrap-used` implied by `-D warnings` error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:36:17 + --> $DIR/get_unwrap.rs:39:17 | LL | let _ = some_slice.get(0).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_slice[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_slice[0]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:36:17 + --> $DIR/get_unwrap.rs:39:17 | LL | let _ = some_slice.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,13 +34,13 @@ LL | let _ = some_slice.get(0).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:37:17 + --> $DIR/get_unwrap.rs:40:17 | LL | let _ = some_vec.get(0).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vec[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_vec[0]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:37:17 + --> $DIR/get_unwrap.rs:40:17 | LL | let _ = some_vec.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,13 +48,13 @@ LL | let _ = some_vec.get(0).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:38:17 + --> $DIR/get_unwrap.rs:41:17 | LL | let _ = some_vecdeque.get(0).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vecdeque[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_vecdeque[0]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:38:17 + --> $DIR/get_unwrap.rs:41:17 | LL | let _ = some_vecdeque.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -62,13 +62,13 @@ LL | let _ = some_vecdeque.get(0).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:39:17 + --> $DIR/get_unwrap.rs:42:17 | LL | let _ = some_hashmap.get(&1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_hashmap[&1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_hashmap[&1]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:39:17 + --> $DIR/get_unwrap.rs:42:17 | LL | let _ = some_hashmap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -76,13 +76,13 @@ LL | let _ = some_hashmap.get(&1).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:40:17 + --> $DIR/get_unwrap.rs:43:17 | LL | let _ = some_btreemap.get(&1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_btreemap[&1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_btreemap[&1]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:40:17 + --> $DIR/get_unwrap.rs:43:17 | LL | let _ = some_btreemap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,13 +90,13 @@ LL | let _ = some_btreemap.get(&1).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:44:21 + --> $DIR/get_unwrap.rs:47:21 | LL | let _: u8 = *boxed_slice.get(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice[1]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:44:22 + --> $DIR/get_unwrap.rs:47:22 | LL | let _: u8 = *boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,13 +104,13 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:49:9 + --> $DIR/get_unwrap.rs:52:9 | LL | *boxed_slice.get_mut(0).unwrap() = 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice[0]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:49:10 + --> $DIR/get_unwrap.rs:52:10 | LL | *boxed_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,13 +118,13 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:50:9 + --> $DIR/get_unwrap.rs:53:9 | LL | *some_slice.get_mut(0).unwrap() = 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_slice[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_slice[0]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:50:10 + --> $DIR/get_unwrap.rs:53:10 | LL | *some_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,13 +132,13 @@ LL | *some_slice.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:51:9 + --> $DIR/get_unwrap.rs:54:9 | LL | *some_vec.get_mut(0).unwrap() = 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:51:10 + --> $DIR/get_unwrap.rs:54:10 | LL | *some_vec.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -146,13 +146,13 @@ LL | *some_vec.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:52:9 + --> $DIR/get_unwrap.rs:55:9 | LL | *some_vecdeque.get_mut(0).unwrap() = 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vecdeque[0]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vecdeque[0]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:52:10 + --> $DIR/get_unwrap.rs:55:10 | LL | *some_vecdeque.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -160,13 +160,13 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1; = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:64:17 + --> $DIR/get_unwrap.rs:67:17 | LL | let _ = some_vec.get(0..1).unwrap().to_vec(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0..1]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:64:17 + --> $DIR/get_unwrap.rs:67:17 | LL | let _ = some_vec.get(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,18 +174,85 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec(); = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/get_unwrap.rs:65:17 + --> $DIR/get_unwrap.rs:68:17 | LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0..1]` error: used `unwrap()` on an `Option` value - --> $DIR/get_unwrap.rs:65:17 + --> $DIR/get_unwrap.rs:68:17 | LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message -error: aborting due to 26 previous errors +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/get_unwrap.rs:80:24 +======= + --> $DIR/get_unwrap.rs:78:24 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) + | +LL | let _x: &i32 = f.get(1 + 2).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `&f[1 + 2]` + +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/get_unwrap.rs:81:18 + | +LL | let _x = f.get(1 + 2).unwrap().to_string(); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `f[1 + 2]` + +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/get_unwrap.rs:84:18 + | +LL | let _x = f.get(1 + 2).unwrap().abs(); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `f[1 + 2]` + +error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/get_unwrap.rs:101:33 + | +LL | let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut rest[linidx(j, k) - linidx(i, k) - 1]` + +error: aborting due to 30 previous errors +======= + --> $DIR/get_unwrap.rs:77:20 +======= + --> $DIR/get_unwrap.rs:79:24 +>>>>>>> 3122e3d78 (use let chains, move assignments out of block, add tests) +======= + --> $DIR/get_unwrap.rs:80:24 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | let _x: &i32 = f.get(1 + 2).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `&f[1 + 2]` + +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/get_unwrap.rs:83:18 + | +LL | let _x = f.get(1 + 2).unwrap().to_string(); + | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `f[1 + 2]` + +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/get_unwrap.rs:86:18 + | +LL | let _x = f.get(1 + 2).unwrap().abs(); + | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `f[1 + 2]` + +error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/get_unwrap.rs:103:33 + | +LL | let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut rest[linidx(j, k) - linidx(i, k) - 1]` + +<<<<<<< HEAD +error: aborting due to 32 previous errors +>>>>>>> 6331c943f (include a ref if argument is not just a numeric literal) +======= +error: aborting due to 30 previous errors +>>>>>>> 3122e3d78 (use let chains, move assignments out of block, add tests) diff --git a/tests/ui/identity_op.fixed b/tests/ui/identity_op.fixed index cac69ef42c41..beb16000eca2 100644 --- a/tests/ui/identity_op.fixed +++ b/tests/ui/identity_op.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::identity_op)] #![allow(unused)] #![allow( diff --git a/tests/ui/identity_op.rs b/tests/ui/identity_op.rs index 33201aad4f64..072e00c00f0a 100644 --- a/tests/ui/identity_op.rs +++ b/tests/ui/identity_op.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::identity_op)] #![allow(unused)] #![allow( diff --git a/tests/ui/if_same_then_else.rs b/tests/ui/if_same_then_else.rs index 07d2002eb27f..dad4543f84c0 100644 --- a/tests/ui/if_same_then_else.rs +++ b/tests/ui/if_same_then_else.rs @@ -21,6 +21,7 @@ fn foo() -> bool { fn if_same_then_else() { if true { + //~^ ERROR: this `if` has identical blocks Foo { bar: 42 }; 0..10; ..; @@ -29,7 +30,6 @@ fn if_same_then_else() { 0..=10; foo(); } else { - //~ ERROR same body as `if` block Foo { bar: 42 }; 0..10; ..; @@ -65,16 +65,16 @@ fn if_same_then_else() { } let _ = if true { + //~^ ERROR: this `if` has identical blocks 0.0 } else { - //~ ERROR same body as `if` block 0.0 }; let _ = if true { + //~^ ERROR: this `if` has identical blocks -0.0 } else { - //~ ERROR same body as `if` block -0.0 }; @@ -88,13 +88,14 @@ fn if_same_then_else() { } let _ = if true { + //~^ ERROR: this `if` has identical blocks 42 } else { - //~ ERROR same body as `if` block 42 }; if true { + //~^ ERROR: this `if` has identical blocks let bar = if true { 42 } else { 43 }; while foo() { @@ -102,7 +103,6 @@ fn if_same_then_else() { } bar + 1; } else { - //~ ERROR same body as `if` block let bar = if true { 42 } else { 43 }; while foo() { diff --git a/tests/ui/if_same_then_else.stderr b/tests/ui/if_same_then_else.stderr index fb23b81d36d7..a34fc565590b 100644 --- a/tests/ui/if_same_then_else.stderr +++ b/tests/ui/if_same_then_else.stderr @@ -3,22 +3,22 @@ error: this `if` has identical blocks | LL | if true { | _____________^ +LL | | LL | | Foo { bar: 42 }; LL | | 0..10; -LL | | ..; ... | LL | | foo(); LL | | } else { | |_____^ | note: same as this - --> $DIR/if_same_then_else.rs:31:12 + --> $DIR/if_same_then_else.rs:32:12 | LL | } else { | ____________^ -LL | | //~ ERROR same body as `if` block LL | | Foo { bar: 42 }; LL | | 0..10; +LL | | ..; ... | LL | | foo(); LL | | } @@ -30,16 +30,16 @@ error: this `if` has identical blocks | LL | let _ = if true { | _____________________^ +LL | | LL | | 0.0 LL | | } else { | |_____^ | note: same as this - --> $DIR/if_same_then_else.rs:69:12 + --> $DIR/if_same_then_else.rs:70:12 | LL | } else { | ____________^ -LL | | //~ ERROR same body as `if` block LL | | 0.0 LL | | }; | |_____^ @@ -49,16 +49,16 @@ error: this `if` has identical blocks | LL | let _ = if true { | _____________________^ +LL | | LL | | -0.0 LL | | } else { | |_____^ | note: same as this - --> $DIR/if_same_then_else.rs:76:12 + --> $DIR/if_same_then_else.rs:77:12 | LL | } else { | ____________^ -LL | | //~ ERROR same body as `if` block LL | | -0.0 LL | | }; | |_____^ @@ -68,16 +68,16 @@ error: this `if` has identical blocks | LL | let _ = if true { | _____________________^ +LL | | LL | | 42 LL | | } else { | |_____^ | note: same as this - --> $DIR/if_same_then_else.rs:92:12 + --> $DIR/if_same_then_else.rs:93:12 | LL | } else { | ____________^ -LL | | //~ ERROR same body as `if` block LL | | 42 LL | | }; | |_____^ @@ -87,22 +87,22 @@ error: this `if` has identical blocks | LL | if true { | _____________^ +LL | | LL | | let bar = if true { 42 } else { 43 }; LL | | -LL | | while foo() { ... | LL | | bar + 1; LL | | } else { | |_____^ | note: same as this - --> $DIR/if_same_then_else.rs:104:12 + --> $DIR/if_same_then_else.rs:105:12 | LL | } else { | ____________^ -LL | | //~ ERROR same body as `if` block LL | | let bar = if true { 42 } else { 43 }; LL | | +LL | | while foo() { ... | LL | | bar + 1; LL | | } diff --git a/tests/ui/if_same_then_else2.rs b/tests/ui/if_same_then_else2.rs index 58167f4446db..0b171f21d0cc 100644 --- a/tests/ui/if_same_then_else2.rs +++ b/tests/ui/if_same_then_else2.rs @@ -5,6 +5,7 @@ clippy::equatable_if_let, clippy::collapsible_if, clippy::ifs_same_cond, + clippy::needless_if, clippy::needless_return, clippy::single_element_loop, clippy::branches_sharing_code @@ -12,6 +13,7 @@ fn if_same_then_else2() -> Result<&'static str, ()> { if true { + //~^ ERROR: this `if` has identical blocks for _ in &[42] { let foo: &Option<_> = &Some::(42); if foo.is_some() { @@ -21,7 +23,6 @@ fn if_same_then_else2() -> Result<&'static str, ()> { } } } else { - //~ ERROR same body as `if` block for _ in &[42] { let bar: &Option<_> = &Some::(42); if bar.is_some() { @@ -33,16 +34,16 @@ fn if_same_then_else2() -> Result<&'static str, ()> { } if true { + //~^ ERROR: this `if` has identical blocks if let Some(a) = Some(42) {} } else { - //~ ERROR same body as `if` block if let Some(a) = Some(42) {} } if true { + //~^ ERROR: this `if` has identical blocks if let (1, .., 3) = (1, 2, 3) {} } else { - //~ ERROR same body as `if` block if let (1, .., 3) = (1, 2, 3) {} } @@ -90,16 +91,16 @@ fn if_same_then_else2() -> Result<&'static str, ()> { // Same NaNs let _ = if true { + //~^ ERROR: this `if` has identical blocks f32::NAN } else { - //~ ERROR same body as `if` block f32::NAN }; if true { + //~^ ERROR: this `if` has identical blocks Ok("foo")?; } else { - //~ ERROR same body as `if` block Ok("foo")?; } @@ -121,6 +122,7 @@ fn if_same_then_else2() -> Result<&'static str, ()> { let foo = "bar"; return Ok(&foo[0..]); } else if true { + //~^ ERROR: this `if` has identical blocks let foo = ""; return Ok(&foo[0..]); } else { diff --git a/tests/ui/if_same_then_else2.stderr b/tests/ui/if_same_then_else2.stderr index 704cfd9669ac..621ceba9c7b2 100644 --- a/tests/ui/if_same_then_else2.stderr +++ b/tests/ui/if_same_then_else2.stderr @@ -1,24 +1,32 @@ error: this `if` has identical blocks - --> $DIR/if_same_then_else2.rs:14:13 + --> $DIR/if_same_then_else2.rs:15:13 | LL | if true { | _____________^ +LL | | LL | | for _ in &[42] { LL | | let foo: &Option<_> = &Some::(42); -LL | | if foo.is_some() { ... | LL | | } LL | | } else { | |_____^ | note: same as this - --> $DIR/if_same_then_else2.rs:23:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/if_same_then_else2.rs:25:12 +======= + --> $DIR/if_same_then_else2.rs:24:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/if_same_then_else2.rs:25:12 +>>>>>>> 5bd97ac17 (Update tests) | LL | } else { | ____________^ -LL | | //~ ERROR same body as `if` block LL | | for _ in &[42] { LL | | let bar: &Option<_> = &Some::(42); +LL | | if bar.is_some() { ... | LL | | } LL | | } @@ -26,93 +34,134 @@ LL | | } = note: `-D clippy::if-same-then-else` implied by `-D warnings` error: this `if` has identical blocks - --> $DIR/if_same_then_else2.rs:35:13 + --> $DIR/if_same_then_else2.rs:36:13 | LL | if true { | _____________^ +LL | | LL | | if let Some(a) = Some(42) {} LL | | } else { | |_____^ | note: same as this - --> $DIR/if_same_then_else2.rs:37:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/if_same_then_else2.rs:39:12 +======= + --> $DIR/if_same_then_else2.rs:38:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/if_same_then_else2.rs:39:12 +>>>>>>> 5bd97ac17 (Update tests) | LL | } else { | ____________^ -LL | | //~ ERROR same body as `if` block LL | | if let Some(a) = Some(42) {} LL | | } | |_____^ error: this `if` has identical blocks - --> $DIR/if_same_then_else2.rs:42:13 + --> $DIR/if_same_then_else2.rs:43:13 | LL | if true { | _____________^ +LL | | LL | | if let (1, .., 3) = (1, 2, 3) {} LL | | } else { | |_____^ | note: same as this - --> $DIR/if_same_then_else2.rs:44:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/if_same_then_else2.rs:46:12 +======= + --> $DIR/if_same_then_else2.rs:45:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/if_same_then_else2.rs:46:12 +>>>>>>> 5bd97ac17 (Update tests) | LL | } else { | ____________^ -LL | | //~ ERROR same body as `if` block LL | | if let (1, .., 3) = (1, 2, 3) {} LL | | } | |_____^ error: this `if` has identical blocks - --> $DIR/if_same_then_else2.rs:92:21 + --> $DIR/if_same_then_else2.rs:93:21 | LL | let _ = if true { | _____________________^ +LL | | LL | | f32::NAN LL | | } else { | |_____^ | note: same as this - --> $DIR/if_same_then_else2.rs:94:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/if_same_then_else2.rs:96:12 +======= + --> $DIR/if_same_then_else2.rs:95:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/if_same_then_else2.rs:96:12 +>>>>>>> 5bd97ac17 (Update tests) | LL | } else { | ____________^ -LL | | //~ ERROR same body as `if` block LL | | f32::NAN LL | | }; | |_____^ error: this `if` has identical blocks - --> $DIR/if_same_then_else2.rs:99:13 + --> $DIR/if_same_then_else2.rs:100:13 | LL | if true { | _____________^ +LL | | LL | | Ok("foo")?; LL | | } else { | |_____^ | note: same as this - --> $DIR/if_same_then_else2.rs:101:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/if_same_then_else2.rs:103:12 +======= + --> $DIR/if_same_then_else2.rs:102:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/if_same_then_else2.rs:103:12 +>>>>>>> 5bd97ac17 (Update tests) | LL | } else { | ____________^ -LL | | //~ ERROR same body as `if` block LL | | Ok("foo")?; LL | | } | |_____^ error: this `if` has identical blocks - --> $DIR/if_same_then_else2.rs:123:20 + --> $DIR/if_same_then_else2.rs:124:20 | LL | } else if true { | ____________________^ +LL | | LL | | let foo = ""; LL | | return Ok(&foo[0..]); LL | | } else { | |_____^ | note: same as this - --> $DIR/if_same_then_else2.rs:126:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/if_same_then_else2.rs:128:12 +======= + --> $DIR/if_same_then_else2.rs:127:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/if_same_then_else2.rs:128:12 +>>>>>>> 5bd97ac17 (Update tests) | LL | } else { | ____________^ diff --git a/tests/ui/ifs_same_cond.rs b/tests/ui/ifs_same_cond.rs index 9ce9a87626a7..85549b9550aa 100644 --- a/tests/ui/ifs_same_cond.rs +++ b/tests/ui/ifs_same_cond.rs @@ -1,5 +1,20 @@ #![warn(clippy::ifs_same_cond)] -#![allow(clippy::if_same_then_else, clippy::comparison_chain)] // all empty blocks +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 26f50395b (Add `needless_if` lint) +#![allow( + clippy::if_same_then_else, + clippy::comparison_chain, + clippy::needless_if, + clippy::needless_else +)] // all empty blocks +<<<<<<< HEAD +======= +#![allow(clippy::if_same_then_else, clippy::comparison_chain, clippy::needless_else)] // all empty blocks +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= +>>>>>>> 26f50395b (Add `needless_if` lint) fn ifs_same_cond() { let a = 0; @@ -7,18 +22,18 @@ fn ifs_same_cond() { if b { } else if b { - //~ ERROR ifs same condition + //~^ ERROR: this `if` has the same condition as a previous `if` } if a == 1 { } else if a == 1 { - //~ ERROR ifs same condition + //~^ ERROR: this `if` has the same condition as a previous `if` } if 2 * a == 1 { } else if 2 * a == 2 { } else if 2 * a == 1 { - //~ ERROR ifs same condition + //~^ ERROR: this `if` has the same condition as a previous `if` } else if a == 1 { } @@ -47,6 +62,7 @@ fn issue10272() { let a = String::from("ha"); if a.contains("ah") { } else if a.contains("ah") { + //~^ ERROR: this `if` has the same condition as a previous `if` // Trigger this lint } else if a.contains("ha") { } else if a == "wow" { diff --git a/tests/ui/ifs_same_cond.stderr b/tests/ui/ifs_same_cond.stderr index 9519f6904cb1..8d70934476cb 100644 --- a/tests/ui/ifs_same_cond.stderr +++ b/tests/ui/ifs_same_cond.stderr @@ -1,48 +1,48 @@ error: this `if` has the same condition as a previous `if` - --> $DIR/ifs_same_cond.rs:9:15 + --> $DIR/ifs_same_cond.rs:14:15 | LL | } else if b { | ^ | note: same as this - --> $DIR/ifs_same_cond.rs:8:8 + --> $DIR/ifs_same_cond.rs:13:8 | LL | if b { | ^ = note: `-D clippy::ifs-same-cond` implied by `-D warnings` error: this `if` has the same condition as a previous `if` - --> $DIR/ifs_same_cond.rs:14:15 + --> $DIR/ifs_same_cond.rs:19:15 | LL | } else if a == 1 { | ^^^^^^ | note: same as this - --> $DIR/ifs_same_cond.rs:13:8 + --> $DIR/ifs_same_cond.rs:18:8 | LL | if a == 1 { | ^^^^^^ error: this `if` has the same condition as a previous `if` - --> $DIR/ifs_same_cond.rs:20:15 + --> $DIR/ifs_same_cond.rs:25:15 | LL | } else if 2 * a == 1 { | ^^^^^^^^^^ | note: same as this - --> $DIR/ifs_same_cond.rs:18:8 + --> $DIR/ifs_same_cond.rs:23:8 | LL | if 2 * a == 1 { | ^^^^^^^^^^ error: this `if` has the same condition as a previous `if` - --> $DIR/ifs_same_cond.rs:49:15 + --> $DIR/ifs_same_cond.rs:54:15 | LL | } else if a.contains("ah") { | ^^^^^^^^^^^^^^^^ | note: same as this - --> $DIR/ifs_same_cond.rs:48:8 + --> $DIR/ifs_same_cond.rs:53:8 | LL | if a.contains("ah") { | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/implicit_clone.fixed b/tests/ui/implicit_clone.fixed index 8ccc3da7b47c..e62db8b40be6 100644 --- a/tests/ui/implicit_clone.fixed +++ b/tests/ui/implicit_clone.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::implicit_clone)] #![allow(clippy::clone_on_copy, clippy::redundant_clone)] use std::borrow::Borrow; diff --git a/tests/ui/implicit_clone.rs b/tests/ui/implicit_clone.rs index 593333126077..88352b06af3c 100644 --- a/tests/ui/implicit_clone.rs +++ b/tests/ui/implicit_clone.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::implicit_clone)] #![allow(clippy::clone_on_copy, clippy::redundant_clone)] use std::borrow::Borrow; diff --git a/tests/ui/implicit_hasher.rs b/tests/ui/implicit_hasher.rs index 35d08a07bc3f..19cbbed4bb45 100644 --- a/tests/ui/implicit_hasher.rs +++ b/tests/ui/implicit_hasher.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![deny(clippy::implicit_hasher)] #![allow(unused)] diff --git a/tests/ui/implicit_return.fixed b/tests/ui/implicit_return.fixed index 5e55b8b67391..64813eafda64 100644 --- a/tests/ui/implicit_return.fixed +++ b/tests/ui/implicit_return.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![warn(clippy::implicit_return)] #![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)] diff --git a/tests/ui/implicit_return.rs b/tests/ui/implicit_return.rs index 76f0a9803520..39d47b110db7 100644 --- a/tests/ui/implicit_return.rs +++ b/tests/ui/implicit_return.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![warn(clippy::implicit_return)] #![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)] diff --git a/tests/ui/implicit_saturating_add.fixed b/tests/ui/implicit_saturating_add.fixed index 7d363d59a6f0..7fc510d6b415 100644 --- a/tests/ui/implicit_saturating_add.fixed +++ b/tests/ui/implicit_saturating_add.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::implicit_saturating_add)] diff --git a/tests/ui/implicit_saturating_add.rs b/tests/ui/implicit_saturating_add.rs index 31a5916277fa..3dcd91f42fed 100644 --- a/tests/ui/implicit_saturating_add.rs +++ b/tests/ui/implicit_saturating_add.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::implicit_saturating_add)] diff --git a/tests/ui/implicit_saturating_sub.fixed b/tests/ui/implicit_saturating_sub.fixed index 93df81b1a7ff..1a11db0982f7 100644 --- a/tests/ui/implicit_saturating_sub.fixed +++ b/tests/ui/implicit_saturating_sub.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_assignments, unused_mut, clippy::assign_op_pattern)] #![warn(clippy::implicit_saturating_sub)] diff --git a/tests/ui/implicit_saturating_sub.rs b/tests/ui/implicit_saturating_sub.rs index 8340bc8264d5..9369df67430c 100644 --- a/tests/ui/implicit_saturating_sub.rs +++ b/tests/ui/implicit_saturating_sub.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_assignments, unused_mut, clippy::assign_op_pattern)] #![warn(clippy::implicit_saturating_sub)] diff --git a/tests/ui/inconsistent_digit_grouping.fixed b/tests/ui/inconsistent_digit_grouping.fixed index dd683e7f746a..06919809ee92 100644 --- a/tests/ui/inconsistent_digit_grouping.fixed +++ b/tests/ui/inconsistent_digit_grouping.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::inconsistent_digit_grouping)] #[deny(clippy::unreadable_literal)] #[allow(unused_variables, clippy::excessive_precision)] diff --git a/tests/ui/inconsistent_digit_grouping.rs b/tests/ui/inconsistent_digit_grouping.rs index d5d27c853c28..04d9125f2bfa 100644 --- a/tests/ui/inconsistent_digit_grouping.rs +++ b/tests/ui/inconsistent_digit_grouping.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::inconsistent_digit_grouping)] #[deny(clippy::unreadable_literal)] #[allow(unused_variables, clippy::excessive_precision)] diff --git a/tests/ui/inconsistent_struct_constructor.fixed b/tests/ui/inconsistent_struct_constructor.fixed index 5aaa00f85172..6571e1a82adc 100644 --- a/tests/ui/inconsistent_struct_constructor.fixed +++ b/tests/ui/inconsistent_struct_constructor.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::inconsistent_struct_constructor)] #![allow(clippy::redundant_field_names)] diff --git a/tests/ui/inconsistent_struct_constructor.rs b/tests/ui/inconsistent_struct_constructor.rs index 2b2dd7f59a4d..4e6e5bcfeb4f 100644 --- a/tests/ui/inconsistent_struct_constructor.rs +++ b/tests/ui/inconsistent_struct_constructor.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::inconsistent_struct_constructor)] #![allow(clippy::redundant_field_names)] diff --git a/tests/ui/incorrect_clone_impl_on_copy_type.fixed b/tests/ui/incorrect_clone_impl_on_copy_type.fixed new file mode 100644 index 000000000000..ac482dcda1ee --- /dev/null +++ b/tests/ui/incorrect_clone_impl_on_copy_type.fixed @@ -0,0 +1,97 @@ +//@run-rustfix +#![allow(clippy::clone_on_copy, unused)] +#![no_main] + +// lint + +struct A(u32); + +impl Clone for A { + fn clone(&self) -> Self { *self } + + +} + +impl Copy for A {} + +// do not lint + +struct B(u32); + +impl Clone for B { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for B {} + +// do not lint derived (clone's implementation is `*self` here anyway) + +#[derive(Clone, Copy)] +struct C(u32); + +// do not lint derived (fr this time) + +struct D(u32); + +#[automatically_derived] +impl Clone for D { + fn clone(&self) -> Self { + Self(self.0) + } + + fn clone_from(&mut self, source: &Self) { + source.clone(); + *self = source.clone(); + } +} + +impl Copy for D {} + +// do not lint if clone is not manually implemented + +struct E(u32); + +#[automatically_derived] +impl Clone for E { + fn clone(&self) -> Self { + Self(self.0) + } + + fn clone_from(&mut self, source: &Self) { + source.clone(); + *self = source.clone(); + } +} + +impl Copy for E {} + +// lint since clone is not derived + +#[derive(Copy)] +struct F(u32); + +impl Clone for F { + fn clone(&self) -> Self { *self } + + +} + +// do not lint since copy has more restrictive bounds + +#[derive(Eq, PartialEq)] +struct Uwu(A); + +impl Clone for Uwu { + fn clone(&self) -> Self { + Self(self.0) + } + + fn clone_from(&mut self, source: &Self) { + source.clone(); + *self = source.clone(); + } +} + +impl Copy for Uwu {} diff --git a/tests/ui/incorrect_clone_impl_on_copy_type.rs b/tests/ui/incorrect_clone_impl_on_copy_type.rs new file mode 100644 index 000000000000..00775874ff58 --- /dev/null +++ b/tests/ui/incorrect_clone_impl_on_copy_type.rs @@ -0,0 +1,107 @@ +//@run-rustfix +#![allow(clippy::clone_on_copy, unused)] +#![no_main] + +// lint + +struct A(u32); + +impl Clone for A { + fn clone(&self) -> Self { + Self(self.0) + } + + fn clone_from(&mut self, source: &Self) { + source.clone(); + *self = source.clone(); + } +} + +impl Copy for A {} + +// do not lint + +struct B(u32); + +impl Clone for B { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for B {} + +// do not lint derived (clone's implementation is `*self` here anyway) + +#[derive(Clone, Copy)] +struct C(u32); + +// do not lint derived (fr this time) + +struct D(u32); + +#[automatically_derived] +impl Clone for D { + fn clone(&self) -> Self { + Self(self.0) + } + + fn clone_from(&mut self, source: &Self) { + source.clone(); + *self = source.clone(); + } +} + +impl Copy for D {} + +// do not lint if clone is not manually implemented + +struct E(u32); + +#[automatically_derived] +impl Clone for E { + fn clone(&self) -> Self { + Self(self.0) + } + + fn clone_from(&mut self, source: &Self) { + source.clone(); + *self = source.clone(); + } +} + +impl Copy for E {} + +// lint since clone is not derived + +#[derive(Copy)] +struct F(u32); + +impl Clone for F { + fn clone(&self) -> Self { + Self(self.0) + } + + fn clone_from(&mut self, source: &Self) { + source.clone(); + *self = source.clone(); + } +} + +// do not lint since copy has more restrictive bounds + +#[derive(Eq, PartialEq)] +struct Uwu(A); + +impl Clone for Uwu { + fn clone(&self) -> Self { + Self(self.0) + } + + fn clone_from(&mut self, source: &Self) { + source.clone(); + *self = source.clone(); + } +} + +impl Copy for Uwu {} diff --git a/tests/ui/incorrect_clone_impl_on_copy_type.stderr b/tests/ui/incorrect_clone_impl_on_copy_type.stderr new file mode 100644 index 000000000000..7bcba8ba45a2 --- /dev/null +++ b/tests/ui/incorrect_clone_impl_on_copy_type.stderr @@ -0,0 +1,40 @@ +error: incorrect implementation of `clone` on a `Copy` type + --> $DIR/incorrect_clone_impl_on_copy_type.rs:10:29 + | +LL | fn clone(&self) -> Self { + | _____________________________^ +LL | | Self(self.0) +LL | | } + | |_____^ help: change this to: `{ *self }` + | + = note: `#[deny(clippy::incorrect_clone_impl_on_copy_type)]` on by default + +error: incorrect implementation of `clone_from` on a `Copy` type + --> $DIR/incorrect_clone_impl_on_copy_type.rs:14:5 + | +LL | / fn clone_from(&mut self, source: &Self) { +LL | | source.clone(); +LL | | *self = source.clone(); +LL | | } + | |_____^ help: remove it + +error: incorrect implementation of `clone` on a `Copy` type + --> $DIR/incorrect_clone_impl_on_copy_type.rs:81:29 + | +LL | fn clone(&self) -> Self { + | _____________________________^ +LL | | Self(self.0) +LL | | } + | |_____^ help: change this to: `{ *self }` + +error: incorrect implementation of `clone_from` on a `Copy` type + --> $DIR/incorrect_clone_impl_on_copy_type.rs:85:5 + | +LL | / fn clone_from(&mut self, source: &Self) { +LL | | source.clone(); +LL | | *self = source.clone(); +LL | | } + | |_____^ help: remove it + +error: aborting due to 4 previous errors + diff --git a/tests/ui/incorrect_partial_ord_impl_on_ord_type.fixed b/tests/ui/incorrect_partial_ord_impl_on_ord_type.fixed new file mode 100644 index 000000000000..dd4fdd98822c --- /dev/null +++ b/tests/ui/incorrect_partial_ord_impl_on_ord_type.fixed @@ -0,0 +1,114 @@ +//@run-rustfix +#![allow(unused)] +#![no_main] + +use std::cmp::Ordering; + +// lint + +#[derive(Eq, PartialEq)] +struct A(u32); + +impl Ord for A { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for A { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } +} + +// do not lint + +#[derive(Eq, PartialEq)] +struct B(u32); + +impl Ord for B { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for B { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +// lint, and give `_` a name + +#[derive(Eq, PartialEq)] +struct C(u32); + +impl Ord for C { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for C { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } +} + +// do not lint derived + +#[derive(Eq, Ord, PartialEq, PartialOrd)] +struct D(u32); + +// do not lint if ord is not manually implemented + +#[derive(Eq, PartialEq)] +struct E(u32); + +impl PartialOrd for E { + fn partial_cmp(&self, other: &Self) -> Option { + todo!(); + } +} + +// do not lint since ord has more restrictive bounds + +#[derive(Eq, PartialEq)] +struct Uwu(A); + +impl Ord for Uwu { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for Uwu { + fn partial_cmp(&self, other: &Self) -> Option { + todo!(); + } +} + +// do not lint since `Rhs` is not `Self` + +#[derive(Eq, PartialEq)] +struct F(u32); + +impl Ord for F { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for F { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl PartialEq for F { + fn eq(&self, other: &u32) -> bool { + todo!(); + } +} + +impl PartialOrd for F { + fn partial_cmp(&self, other: &u32) -> Option { + todo!(); + } +} diff --git a/tests/ui/incorrect_partial_ord_impl_on_ord_type.rs b/tests/ui/incorrect_partial_ord_impl_on_ord_type.rs new file mode 100644 index 000000000000..522e82299c0a --- /dev/null +++ b/tests/ui/incorrect_partial_ord_impl_on_ord_type.rs @@ -0,0 +1,118 @@ +//@run-rustfix +#![allow(unused)] +#![no_main] + +use std::cmp::Ordering; + +// lint + +#[derive(Eq, PartialEq)] +struct A(u32); + +impl Ord for A { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for A { + fn partial_cmp(&self, other: &Self) -> Option { + todo!(); + } +} + +// do not lint + +#[derive(Eq, PartialEq)] +struct B(u32); + +impl Ord for B { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for B { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +// lint, and give `_` a name + +#[derive(Eq, PartialEq)] +struct C(u32); + +impl Ord for C { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for C { + fn partial_cmp(&self, _: &Self) -> Option { + todo!(); + } +} + +// do not lint derived + +#[derive(Eq, Ord, PartialEq, PartialOrd)] +struct D(u32); + +// do not lint if ord is not manually implemented + +#[derive(Eq, PartialEq)] +struct E(u32); + +impl PartialOrd for E { + fn partial_cmp(&self, other: &Self) -> Option { + todo!(); + } +} + +// do not lint since ord has more restrictive bounds + +#[derive(Eq, PartialEq)] +struct Uwu(A); + +impl Ord for Uwu { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for Uwu { + fn partial_cmp(&self, other: &Self) -> Option { + todo!(); + } +} + +// do not lint since `Rhs` is not `Self` + +#[derive(Eq, PartialEq)] +struct F(u32); + +impl Ord for F { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for F { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl PartialEq for F { + fn eq(&self, other: &u32) -> bool { + todo!(); + } +} + +impl PartialOrd for F { + fn partial_cmp(&self, other: &u32) -> Option { + todo!(); + } +} diff --git a/tests/ui/incorrect_partial_ord_impl_on_ord_type.stderr b/tests/ui/incorrect_partial_ord_impl_on_ord_type.stderr new file mode 100644 index 000000000000..0e477798c406 --- /dev/null +++ b/tests/ui/incorrect_partial_ord_impl_on_ord_type.stderr @@ -0,0 +1,31 @@ +error: incorrect implementation of `partial_cmp` on an `Ord` type + --> $DIR/incorrect_partial_ord_impl_on_ord_type.rs:18:1 + | +LL | / impl PartialOrd for A { +LL | | fn partial_cmp(&self, other: &Self) -> Option { + | | _____________________________________________________________- +LL | || todo!(); +LL | || } + | ||_____- help: change this to: `{ Some(self.cmp(other)) }` +LL | | } + | |__^ + | + = note: `#[deny(clippy::incorrect_partial_ord_impl_on_ord_type)]` on by default + +error: incorrect implementation of `partial_cmp` on an `Ord` type + --> $DIR/incorrect_partial_ord_impl_on_ord_type.rs:52:1 + | +LL | / impl PartialOrd for C { +LL | | fn partial_cmp(&self, _: &Self) -> Option { +LL | | todo!(); +LL | | } +LL | | } + | |_^ + | +help: change this to + | +LL | fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } + | ~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/indexing_slicing_index.rs b/tests/ui/indexing_slicing_index.rs index 26abc9edb5e4..16f9e47e8532 100644 --- a/tests/ui/indexing_slicing_index.rs +++ b/tests/ui/indexing_slicing_index.rs @@ -3,7 +3,12 @@ // We also check the out_of_bounds_indexing lint here, because it lints similar things and // we want to avoid false positives. #![warn(clippy::out_of_bounds_indexing)] -#![allow(unconditional_panic, clippy::no_effect, clippy::unnecessary_operation)] +#![allow( + unconditional_panic, + clippy::no_effect, + clippy::unnecessary_operation, + clippy::useless_vec +)] const ARR: [i32; 2] = [1, 2]; const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false. diff --git a/tests/ui/indexing_slicing_index.stderr b/tests/ui/indexing_slicing_index.stderr index 8fd77913a3fd..f4357c1d592d 100644 --- a/tests/ui/indexing_slicing_index.stderr +++ b/tests/ui/indexing_slicing_index.stderr @@ -1,5 +1,5 @@ error: indexing may panic - --> $DIR/indexing_slicing_index.rs:9:20 + --> $DIR/indexing_slicing_index.rs:14:20 | LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false. | ^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-re = note: `-D clippy::indexing-slicing` implied by `-D warnings` error: indexing may panic - --> $DIR/indexing_slicing_index.rs:10:24 + --> $DIR/indexing_slicing_index.rs:15:24 | LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts. | ^^^^^^^^^^^ @@ -18,19 +18,19 @@ LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts. = note: the suggestion might not be applicable in constant blocks error[E0080]: evaluation of `main::{constant#3}` failed - --> $DIR/indexing_slicing_index.rs:31:14 + --> $DIR/indexing_slicing_index.rs:36:14 | LL | const { &ARR[idx4()] }; // This should be linted, since `suppress-restriction-lint-in-const` default is false. | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 note: erroneous constant used - --> $DIR/indexing_slicing_index.rs:31:5 + --> $DIR/indexing_slicing_index.rs:36:5 | LL | const { &ARR[idx4()] }; // This should be linted, since `suppress-restriction-lint-in-const` default is false. | ^^^^^^^^^^^^^^^^^^^^^^ error: indexing may panic - --> $DIR/indexing_slicing_index.rs:22:5 + --> $DIR/indexing_slicing_index.rs:27:5 | LL | x[index]; | ^^^^^^^^ @@ -38,7 +38,7 @@ LL | x[index]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/indexing_slicing_index.rs:30:14 + --> $DIR/indexing_slicing_index.rs:35:14 | LL | const { &ARR[idx()] }; // This should be linted, since `suppress-restriction-lint-in-const` default is false. | ^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | const { &ARR[idx()] }; // This should be linted, since `suppress-restri = note: the suggestion might not be applicable in constant blocks error: indexing may panic - --> $DIR/indexing_slicing_index.rs:31:14 + --> $DIR/indexing_slicing_index.rs:36:14 | LL | const { &ARR[idx4()] }; // This should be linted, since `suppress-restriction-lint-in-const` default is false. | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | const { &ARR[idx4()] }; // This should be linted, since `suppress-restr = note: the suggestion might not be applicable in constant blocks error: indexing may panic - --> $DIR/indexing_slicing_index.rs:38:5 + --> $DIR/indexing_slicing_index.rs:43:5 | LL | v[0]; | ^^^^ @@ -64,7 +64,7 @@ LL | v[0]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/indexing_slicing_index.rs:39:5 + --> $DIR/indexing_slicing_index.rs:44:5 | LL | v[10]; | ^^^^^ @@ -72,7 +72,7 @@ LL | v[10]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/indexing_slicing_index.rs:40:5 + --> $DIR/indexing_slicing_index.rs:45:5 | LL | v[1 << 3]; | ^^^^^^^^^ @@ -80,7 +80,7 @@ LL | v[1 << 3]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/indexing_slicing_index.rs:46:5 + --> $DIR/indexing_slicing_index.rs:51:5 | LL | v[N]; | ^^^^ @@ -88,7 +88,7 @@ LL | v[N]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/indexing_slicing_index.rs:47:5 + --> $DIR/indexing_slicing_index.rs:52:5 | LL | v[M]; | ^^^^ @@ -96,7 +96,7 @@ LL | v[M]; = help: consider using `.get(n)` or `.get_mut(n)` instead error[E0080]: evaluation of constant value failed - --> $DIR/indexing_slicing_index.rs:10:24 + --> $DIR/indexing_slicing_index.rs:15:24 | LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts. | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 diff --git a/tests/ui/indexing_slicing_slice.rs b/tests/ui/indexing_slicing_slice.rs index 7b107db39f02..939b6ac36bde 100644 --- a/tests/ui/indexing_slicing_slice.rs +++ b/tests/ui/indexing_slicing_slice.rs @@ -2,7 +2,7 @@ // We also check the out_of_bounds_indexing lint here, because it lints similar things and // we want to avoid false positives. #![warn(clippy::out_of_bounds_indexing)] -#![allow(clippy::no_effect, clippy::unnecessary_operation)] +#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::useless_vec)] fn main() { let x = [1, 2, 3, 4]; diff --git a/tests/ui/inefficient_to_string.fixed b/tests/ui/inefficient_to_string.fixed index c972b9419ef7..557f7fb73585 100644 --- a/tests/ui/inefficient_to_string.fixed +++ b/tests/ui/inefficient_to_string.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::inefficient_to_string)] use std::borrow::Cow; diff --git a/tests/ui/inefficient_to_string.rs b/tests/ui/inefficient_to_string.rs index acdc55aa0d69..6503001e345b 100644 --- a/tests/ui/inefficient_to_string.rs +++ b/tests/ui/inefficient_to_string.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::inefficient_to_string)] use std::borrow::Cow; diff --git a/tests/ui/infallible_destructuring_match.fixed b/tests/ui/infallible_destructuring_match.fixed index 61985e56b769..e396ae94aaab 100644 --- a/tests/ui/infallible_destructuring_match.fixed +++ b/tests/ui/infallible_destructuring_match.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(exhaustive_patterns, never_type)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow(clippy::let_and_return)] diff --git a/tests/ui/infallible_destructuring_match.rs b/tests/ui/infallible_destructuring_match.rs index f2768245bbc4..3fce7bbb6c71 100644 --- a/tests/ui/infallible_destructuring_match.rs +++ b/tests/ui/infallible_destructuring_match.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(exhaustive_patterns, never_type)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow(clippy::let_and_return)] diff --git a/tests/ui/infallible_destructuring_match.stderr b/tests/ui/infallible_destructuring_match.stderr index f8a50f0223d6..004260a1d648 100644 --- a/tests/ui/infallible_destructuring_match.stderr +++ b/tests/ui/infallible_destructuring_match.stderr @@ -4,7 +4,7 @@ error: you seem to be trying to use `match` to destructure a single infallible p LL | / let data = match wrapper { LL | | SingleVariantEnum::Variant(i) => i, LL | | }; - | |______^ help: try this: `let SingleVariantEnum::Variant(data) = wrapper;` + | |______^ help: try: `let SingleVariantEnum::Variant(data) = wrapper;` | = note: `-D clippy::infallible-destructuring-match` implied by `-D warnings` @@ -14,7 +14,7 @@ error: you seem to be trying to use `match` to destructure a single infallible p LL | / let data = match wrapper { LL | | TupleStruct(i) => i, LL | | }; - | |______^ help: try this: `let TupleStruct(data) = wrapper;` + | |______^ help: try: `let TupleStruct(data) = wrapper;` error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let` --> $DIR/infallible_destructuring_match.rs:85:5 @@ -22,7 +22,7 @@ error: you seem to be trying to use `match` to destructure a single infallible p LL | / let data = match wrapper { LL | | TupleStructWithNonCopy(ref n) => n, LL | | }; - | |______^ help: try this: `let TupleStructWithNonCopy(ref data) = wrapper;` + | |______^ help: try: `let TupleStructWithNonCopy(ref data) = wrapper;` error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let` --> $DIR/infallible_destructuring_match.rs:104:5 @@ -30,7 +30,7 @@ error: you seem to be trying to use `match` to destructure a single infallible p LL | / let data = match wrapper { LL | | Ok(i) => i, LL | | }; - | |______^ help: try this: `let Ok(data) = wrapper;` + | |______^ help: try: `let Ok(data) = wrapper;` error: aborting due to 4 previous errors diff --git a/tests/ui/infinite_loop.stderr b/tests/ui/infinite_loop.stderr index 85258b9d64f9..701b3cd19041 100644 --- a/tests/ui/infinite_loop.stderr +++ b/tests/ui/infinite_loop.stderr @@ -1,3 +1,11 @@ +error: this argument is a mutable reference, but not used mutably + --> $DIR/infinite_loop.rs:7:17 + | +LL | fn fn_mutref(i: &mut i32) { + | ^^^^^^^^ help: consider changing to: `&i32` + | + = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` + error: variables in the condition are not mutated in the loop body --> $DIR/infinite_loop.rs:20:11 | @@ -91,5 +99,5 @@ LL | while y < 10 { = note: this loop contains `return`s or `break`s = help: rewrite it as `if cond { loop { } }` -error: aborting due to 11 previous errors +error: aborting due to 12 previous errors diff --git a/tests/ui/inline_fn_without_body.fixed b/tests/ui/inline_fn_without_body.fixed index fe21a71a42c2..9c5819558fea 100644 --- a/tests/ui/inline_fn_without_body.fixed +++ b/tests/ui/inline_fn_without_body.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::inline_fn_without_body)] #![allow(clippy::inline_always)] diff --git a/tests/ui/inline_fn_without_body.rs b/tests/ui/inline_fn_without_body.rs index 507469894665..43ffaf8122b6 100644 --- a/tests/ui/inline_fn_without_body.rs +++ b/tests/ui/inline_fn_without_body.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::inline_fn_without_body)] #![allow(clippy::inline_always)] diff --git a/tests/ui/int_plus_one.fixed b/tests/ui/int_plus_one.fixed index 642830f24f58..5a36ec462d4c 100644 --- a/tests/ui/int_plus_one.fixed +++ b/tests/ui/int_plus_one.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[allow(clippy::no_effect, clippy::unnecessary_operation)] #[warn(clippy::int_plus_one)] diff --git a/tests/ui/int_plus_one.rs b/tests/ui/int_plus_one.rs index 0755a0c79d28..bffa4afd6b08 100644 --- a/tests/ui/int_plus_one.rs +++ b/tests/ui/int_plus_one.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[allow(clippy::no_effect, clippy::unnecessary_operation)] #[warn(clippy::int_plus_one)] diff --git a/tests/ui/integer_arithmetic.rs b/tests/ui/integer_arithmetic.rs index 8dfdee662b9d..988764f49565 100644 --- a/tests/ui/integer_arithmetic.rs +++ b/tests/ui/integer_arithmetic.rs @@ -1,6 +1,39 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) +//@aux-build:proc_macro_derive.rs +======= +// aux-build:proc_macro_derive.rs +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +<<<<<<< HEAD +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +// aux-build:proc_macro_derive.rs +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +>>>>>>> 4da6e7e06 (rebase attempt) + #![warn(clippy::integer_arithmetic, clippy::float_arithmetic)] #![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::op_ref)] +extern crate proc_macro_derive; + +#[derive(proc_macro_derive::ShadowDerive)] +pub struct Nothing; + #[rustfmt::skip] fn main() { let mut i = 1i32; diff --git a/tests/ui/integer_arithmetic.stderr b/tests/ui/integer_arithmetic.stderr index 9a795b1f2915..add3b6b90fa2 100644 --- a/tests/ui/integer_arithmetic.stderr +++ b/tests/ui/integer_arithmetic.stderr @@ -1,5 +1,5 @@ error: this operation will panic at runtime - --> $DIR/integer_arithmetic.rs:30:5 + --> $DIR/integer_arithmetic.rs:37:5 | LL | i /= 0; | ^^^^^^ attempt to divide `_` by zero @@ -7,13 +7,13 @@ LL | i /= 0; = note: `#[deny(unconditional_panic)]` on by default error: this operation will panic at runtime - --> $DIR/integer_arithmetic.rs:35:5 + --> $DIR/integer_arithmetic.rs:42:5 | LL | i %= 0; | ^^^^^^ attempt to calculate the remainder of `_` with a divisor of zero error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:9:5 + --> $DIR/integer_arithmetic.rs:16:5 | LL | 1 + i; | ^^^^^ @@ -21,146 +21,146 @@ LL | 1 + i; = note: `-D clippy::integer-arithmetic` implied by `-D warnings` error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:10:5 + --> $DIR/integer_arithmetic.rs:17:5 | LL | i * 2; | ^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:11:5 + --> $DIR/integer_arithmetic.rs:18:5 | LL | / 1 % LL | | i / 2; // no error, this is part of the expression in the preceding line | |_____^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:13:5 + --> $DIR/integer_arithmetic.rs:20:5 | LL | i - 2 + 2 - i; | ^^^^^^^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:14:5 + --> $DIR/integer_arithmetic.rs:21:5 | LL | -i; | ^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:15:5 + --> $DIR/integer_arithmetic.rs:22:5 | LL | i >> 1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:16:5 + --> $DIR/integer_arithmetic.rs:23:5 | LL | i << 1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:26:5 + --> $DIR/integer_arithmetic.rs:33:5 | LL | i += 1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:27:5 + --> $DIR/integer_arithmetic.rs:34:5 | LL | i -= 1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:28:5 + --> $DIR/integer_arithmetic.rs:35:5 | LL | i *= 2; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:31:11 + --> $DIR/integer_arithmetic.rs:38:11 | LL | i /= -1; | ^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:32:5 + --> $DIR/integer_arithmetic.rs:39:5 | LL | i /= var1; | ^^^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:33:5 + --> $DIR/integer_arithmetic.rs:40:5 | LL | i /= var2; | ^^^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:36:11 + --> $DIR/integer_arithmetic.rs:43:11 | LL | i %= -1; | ^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:37:5 + --> $DIR/integer_arithmetic.rs:44:5 | LL | i %= var1; | ^^^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:38:5 + --> $DIR/integer_arithmetic.rs:45:5 | LL | i %= var2; | ^^^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:39:5 + --> $DIR/integer_arithmetic.rs:46:5 | LL | i <<= 3; | ^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:40:5 + --> $DIR/integer_arithmetic.rs:47:5 | LL | i >>= 2; | ^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:82:5 + --> $DIR/integer_arithmetic.rs:89:5 | LL | 3 + &1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:83:5 + --> $DIR/integer_arithmetic.rs:90:5 | LL | &3 + 1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:84:5 + --> $DIR/integer_arithmetic.rs:91:5 | LL | &3 + &1; | ^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:89:5 + --> $DIR/integer_arithmetic.rs:96:5 | LL | a + x | ^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:93:5 + --> $DIR/integer_arithmetic.rs:100:5 | LL | x + y | ^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:97:5 + --> $DIR/integer_arithmetic.rs:104:5 | LL | x + y | ^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:101:5 + --> $DIR/integer_arithmetic.rs:108:5 | LL | (&x + &y) | ^^^^^^^^^ diff --git a/tests/ui/into_iter_on_ref.fixed b/tests/ui/into_iter_on_ref.fixed index b77f17944d89..af197e33fd83 100644 --- a/tests/ui/into_iter_on_ref.fixed +++ b/tests/ui/into_iter_on_ref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::useless_vec, clippy::needless_borrow)] #![warn(clippy::into_iter_on_ref)] @@ -11,35 +11,35 @@ fn main() { for _ in &vec![X, X] {} let _ = vec![1, 2, 3].into_iter(); - let _ = (&vec![1, 2, 3]).iter(); //~ WARN equivalent to .iter() - let _ = vec![1, 2, 3].into_boxed_slice().iter(); //~ WARN equivalent to .iter() - let _ = std::rc::Rc::from(&[X][..]).iter(); //~ WARN equivalent to .iter() - let _ = std::sync::Arc::from(&[X][..]).iter(); //~ WARN equivalent to .iter() + let _ = (&vec![1, 2, 3]).iter(); //~ ERROR: equivalent to `.iter() + let _ = vec![1, 2, 3].into_boxed_slice().iter(); //~ ERROR: equivalent to `.iter() + let _ = std::rc::Rc::from(&[X][..]).iter(); //~ ERROR: equivalent to `.iter() + let _ = std::sync::Arc::from(&[X][..]).iter(); //~ ERROR: equivalent to `.iter() - let _ = (&&&&&&&[1, 2, 3]).iter(); //~ ERROR equivalent to .iter() - let _ = (&&&&mut &&&[1, 2, 3]).iter(); //~ ERROR equivalent to .iter() - let _ = (&mut &mut &mut [1, 2, 3]).iter_mut(); //~ ERROR equivalent to .iter_mut() + let _ = (&&&&&&&[1, 2, 3]).iter(); //~ ERROR: equivalent to `.iter() + let _ = (&&&&mut &&&[1, 2, 3]).iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut &mut &mut [1, 2, 3]).iter_mut(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&Some(4)).iter(); //~ WARN equivalent to .iter() - let _ = (&mut Some(5)).iter_mut(); //~ WARN equivalent to .iter_mut() - let _ = (&Ok::<_, i32>(6)).iter(); //~ WARN equivalent to .iter() - let _ = (&mut Err::(7)).iter_mut(); //~ WARN equivalent to .iter_mut() - let _ = (&Vec::::new()).iter(); //~ WARN equivalent to .iter() - let _ = (&mut Vec::::new()).iter_mut(); //~ WARN equivalent to .iter_mut() - let _ = (&BTreeMap::::new()).iter(); //~ WARN equivalent to .iter() - let _ = (&mut BTreeMap::::new()).iter_mut(); //~ WARN equivalent to .iter_mut() - let _ = (&VecDeque::::new()).iter(); //~ WARN equivalent to .iter() - let _ = (&mut VecDeque::::new()).iter_mut(); //~ WARN equivalent to .iter_mut() - let _ = (&LinkedList::::new()).iter(); //~ WARN equivalent to .iter() - let _ = (&mut LinkedList::::new()).iter_mut(); //~ WARN equivalent to .iter_mut() - let _ = (&HashMap::::new()).iter(); //~ WARN equivalent to .iter() - let _ = (&mut HashMap::::new()).iter_mut(); //~ WARN equivalent to .iter_mut() + let _ = (&Some(4)).iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut Some(5)).iter_mut(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&Ok::<_, i32>(6)).iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut Err::(7)).iter_mut(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&Vec::::new()).iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut Vec::::new()).iter_mut(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&BTreeMap::::new()).iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut BTreeMap::::new()).iter_mut(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&VecDeque::::new()).iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut VecDeque::::new()).iter_mut(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&LinkedList::::new()).iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut LinkedList::::new()).iter_mut(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&HashMap::::new()).iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut HashMap::::new()).iter_mut(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&BTreeSet::::new()).iter(); //~ WARN equivalent to .iter() - let _ = (&BinaryHeap::::new()).iter(); //~ WARN equivalent to .iter() - let _ = (&HashSet::::new()).iter(); //~ WARN equivalent to .iter() - let _ = std::path::Path::new("12/34").iter(); //~ WARN equivalent to .iter() - let _ = std::path::PathBuf::from("12/34").iter(); //~ ERROR equivalent to .iter() + let _ = (&BTreeSet::::new()).iter(); //~ ERROR: equivalent to `.iter() + let _ = (&BinaryHeap::::new()).iter(); //~ ERROR: equivalent to `.iter() + let _ = (&HashSet::::new()).iter(); //~ ERROR: equivalent to `.iter() + let _ = std::path::Path::new("12/34").iter(); //~ ERROR: equivalent to `.iter() + let _ = std::path::PathBuf::from("12/34").iter(); //~ ERROR: equivalent to `.iter() - let _ = (&[1, 2, 3]).iter().next(); //~ WARN equivalent to .iter() + let _ = (&[1, 2, 3]).iter().next(); //~ ERROR: equivalent to `.iter() } diff --git a/tests/ui/into_iter_on_ref.rs b/tests/ui/into_iter_on_ref.rs index 3854bb05af8f..3ac13d7dd3e1 100644 --- a/tests/ui/into_iter_on_ref.rs +++ b/tests/ui/into_iter_on_ref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::useless_vec, clippy::needless_borrow)] #![warn(clippy::into_iter_on_ref)] @@ -11,35 +11,35 @@ fn main() { for _ in &vec![X, X] {} let _ = vec![1, 2, 3].into_iter(); - let _ = (&vec![1, 2, 3]).into_iter(); //~ WARN equivalent to .iter() - let _ = vec![1, 2, 3].into_boxed_slice().into_iter(); //~ WARN equivalent to .iter() - let _ = std::rc::Rc::from(&[X][..]).into_iter(); //~ WARN equivalent to .iter() - let _ = std::sync::Arc::from(&[X][..]).into_iter(); //~ WARN equivalent to .iter() + let _ = (&vec![1, 2, 3]).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = vec![1, 2, 3].into_boxed_slice().into_iter(); //~ ERROR: equivalent to `.iter() + let _ = std::rc::Rc::from(&[X][..]).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = std::sync::Arc::from(&[X][..]).into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&&&&&&&[1, 2, 3]).into_iter(); //~ ERROR equivalent to .iter() - let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); //~ ERROR equivalent to .iter() - let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); //~ ERROR equivalent to .iter_mut() + let _ = (&&&&&&&[1, 2, 3]).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&Some(4)).into_iter(); //~ WARN equivalent to .iter() - let _ = (&mut Some(5)).into_iter(); //~ WARN equivalent to .iter_mut() - let _ = (&Ok::<_, i32>(6)).into_iter(); //~ WARN equivalent to .iter() - let _ = (&mut Err::(7)).into_iter(); //~ WARN equivalent to .iter_mut() - let _ = (&Vec::::new()).into_iter(); //~ WARN equivalent to .iter() - let _ = (&mut Vec::::new()).into_iter(); //~ WARN equivalent to .iter_mut() - let _ = (&BTreeMap::::new()).into_iter(); //~ WARN equivalent to .iter() - let _ = (&mut BTreeMap::::new()).into_iter(); //~ WARN equivalent to .iter_mut() - let _ = (&VecDeque::::new()).into_iter(); //~ WARN equivalent to .iter() - let _ = (&mut VecDeque::::new()).into_iter(); //~ WARN equivalent to .iter_mut() - let _ = (&LinkedList::::new()).into_iter(); //~ WARN equivalent to .iter() - let _ = (&mut LinkedList::::new()).into_iter(); //~ WARN equivalent to .iter_mut() - let _ = (&HashMap::::new()).into_iter(); //~ WARN equivalent to .iter() - let _ = (&mut HashMap::::new()).into_iter(); //~ WARN equivalent to .iter_mut() + let _ = (&Some(4)).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut Some(5)).into_iter(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&Ok::<_, i32>(6)).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut Err::(7)).into_iter(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&Vec::::new()).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut Vec::::new()).into_iter(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&BTreeMap::::new()).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut BTreeMap::::new()).into_iter(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&VecDeque::::new()).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut VecDeque::::new()).into_iter(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&LinkedList::::new()).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut LinkedList::::new()).into_iter(); //~ ERROR: equivalent to `.iter_mut() + let _ = (&HashMap::::new()).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = (&mut HashMap::::new()).into_iter(); //~ ERROR: equivalent to `.iter_mut() - let _ = (&BTreeSet::::new()).into_iter(); //~ WARN equivalent to .iter() - let _ = (&BinaryHeap::::new()).into_iter(); //~ WARN equivalent to .iter() - let _ = (&HashSet::::new()).into_iter(); //~ WARN equivalent to .iter() - let _ = std::path::Path::new("12/34").into_iter(); //~ WARN equivalent to .iter() - let _ = std::path::PathBuf::from("12/34").into_iter(); //~ ERROR equivalent to .iter() + let _ = (&BTreeSet::::new()).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = (&BinaryHeap::::new()).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = (&HashSet::::new()).into_iter(); //~ ERROR: equivalent to `.iter() + let _ = std::path::Path::new("12/34").into_iter(); //~ ERROR: equivalent to `.iter() + let _ = std::path::PathBuf::from("12/34").into_iter(); //~ ERROR: equivalent to `.iter() - let _ = (&[1, 2, 3]).into_iter().next(); //~ WARN equivalent to .iter() + let _ = (&[1, 2, 3]).into_iter().next(); //~ ERROR: equivalent to `.iter() } diff --git a/tests/ui/into_iter_on_ref.stderr b/tests/ui/into_iter_on_ref.stderr index 28003b365bbd..06014a93f8c1 100644 --- a/tests/ui/into_iter_on_ref.stderr +++ b/tests/ui/into_iter_on_ref.stderr @@ -1,7 +1,7 @@ error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec` --> $DIR/into_iter_on_ref.rs:14:30 | -LL | let _ = (&vec![1, 2, 3]).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = (&vec![1, 2, 3]).into_iter(); | ^^^^^^^^^ help: call directly: `iter` | = note: `-D clippy::into-iter-on-ref` implied by `-D warnings` @@ -9,157 +9,157 @@ LL | let _ = (&vec![1, 2, 3]).into_iter(); //~ WARN equivalent to .iter() error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice` --> $DIR/into_iter_on_ref.rs:15:46 | -LL | let _ = vec![1, 2, 3].into_boxed_slice().into_iter(); //~ WARN equivalent to .iter() +LL | let _ = vec![1, 2, 3].into_boxed_slice().into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice` --> $DIR/into_iter_on_ref.rs:16:41 | -LL | let _ = std::rc::Rc::from(&[X][..]).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = std::rc::Rc::from(&[X][..]).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice` --> $DIR/into_iter_on_ref.rs:17:44 | -LL | let _ = std::sync::Arc::from(&[X][..]).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = std::sync::Arc::from(&[X][..]).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` --> $DIR/into_iter_on_ref.rs:19:32 | -LL | let _ = (&&&&&&&[1, 2, 3]).into_iter(); //~ ERROR equivalent to .iter() +LL | let _ = (&&&&&&&[1, 2, 3]).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` --> $DIR/into_iter_on_ref.rs:20:36 | -LL | let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); //~ ERROR equivalent to .iter() +LL | let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `array` --> $DIR/into_iter_on_ref.rs:21:40 | -LL | let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); //~ ERROR equivalent to .iter_mut() +LL | let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Option` --> $DIR/into_iter_on_ref.rs:23:24 | -LL | let _ = (&Some(4)).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = (&Some(4)).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Option` --> $DIR/into_iter_on_ref.rs:24:28 | -LL | let _ = (&mut Some(5)).into_iter(); //~ WARN equivalent to .iter_mut() +LL | let _ = (&mut Some(5)).into_iter(); | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Result` --> $DIR/into_iter_on_ref.rs:25:32 | -LL | let _ = (&Ok::<_, i32>(6)).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = (&Ok::<_, i32>(6)).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Result` --> $DIR/into_iter_on_ref.rs:26:37 | -LL | let _ = (&mut Err::(7)).into_iter(); //~ WARN equivalent to .iter_mut() +LL | let _ = (&mut Err::(7)).into_iter(); | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec` --> $DIR/into_iter_on_ref.rs:27:34 | -LL | let _ = (&Vec::::new()).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = (&Vec::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Vec` --> $DIR/into_iter_on_ref.rs:28:38 | -LL | let _ = (&mut Vec::::new()).into_iter(); //~ WARN equivalent to .iter_mut() +LL | let _ = (&mut Vec::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeMap` --> $DIR/into_iter_on_ref.rs:29:44 | -LL | let _ = (&BTreeMap::::new()).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = (&BTreeMap::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `BTreeMap` --> $DIR/into_iter_on_ref.rs:30:48 | -LL | let _ = (&mut BTreeMap::::new()).into_iter(); //~ WARN equivalent to .iter_mut() +LL | let _ = (&mut BTreeMap::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `VecDeque` --> $DIR/into_iter_on_ref.rs:31:39 | -LL | let _ = (&VecDeque::::new()).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = (&VecDeque::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `VecDeque` --> $DIR/into_iter_on_ref.rs:32:43 | -LL | let _ = (&mut VecDeque::::new()).into_iter(); //~ WARN equivalent to .iter_mut() +LL | let _ = (&mut VecDeque::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `LinkedList` --> $DIR/into_iter_on_ref.rs:33:41 | -LL | let _ = (&LinkedList::::new()).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = (&LinkedList::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `LinkedList` --> $DIR/into_iter_on_ref.rs:34:45 | -LL | let _ = (&mut LinkedList::::new()).into_iter(); //~ WARN equivalent to .iter_mut() +LL | let _ = (&mut LinkedList::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashMap` --> $DIR/into_iter_on_ref.rs:35:43 | -LL | let _ = (&HashMap::::new()).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = (&HashMap::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `HashMap` --> $DIR/into_iter_on_ref.rs:36:47 | -LL | let _ = (&mut HashMap::::new()).into_iter(); //~ WARN equivalent to .iter_mut() +LL | let _ = (&mut HashMap::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter_mut` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeSet` --> $DIR/into_iter_on_ref.rs:38:39 | -LL | let _ = (&BTreeSet::::new()).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = (&BTreeSet::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BinaryHeap` --> $DIR/into_iter_on_ref.rs:39:41 | -LL | let _ = (&BinaryHeap::::new()).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = (&BinaryHeap::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashSet` --> $DIR/into_iter_on_ref.rs:40:38 | -LL | let _ = (&HashSet::::new()).into_iter(); //~ WARN equivalent to .iter() +LL | let _ = (&HashSet::::new()).into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Path` --> $DIR/into_iter_on_ref.rs:41:43 | -LL | let _ = std::path::Path::new("12/34").into_iter(); //~ WARN equivalent to .iter() +LL | let _ = std::path::Path::new("12/34").into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `PathBuf` --> $DIR/into_iter_on_ref.rs:42:47 | -LL | let _ = std::path::PathBuf::from("12/34").into_iter(); //~ ERROR equivalent to .iter() +LL | let _ = std::path::PathBuf::from("12/34").into_iter(); | ^^^^^^^^^ help: call directly: `iter` error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array` --> $DIR/into_iter_on_ref.rs:44:26 | -LL | let _ = (&[1, 2, 3]).into_iter().next(); //~ WARN equivalent to .iter() +LL | let _ = (&[1, 2, 3]).into_iter().next(); | ^^^^^^^^^ help: call directly: `iter` error: aborting due to 27 previous errors diff --git a/tests/ui/invalid_null_ptr_usage.fixed b/tests/ui/invalid_null_ptr_usage.fixed index 4f5322ebf202..9264fb7e9e7d 100644 --- a/tests/ui/invalid_null_ptr_usage.fixed +++ b/tests/ui/invalid_null_ptr_usage.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix fn main() { unsafe { diff --git a/tests/ui/invalid_null_ptr_usage.rs b/tests/ui/invalid_null_ptr_usage.rs index ae51c52d8af0..80c942d77572 100644 --- a/tests/ui/invalid_null_ptr_usage.rs +++ b/tests/ui/invalid_null_ptr_usage.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix fn main() { unsafe { diff --git a/tests/ui/invalid_utf8_in_unchecked.rs b/tests/ui/invalid_utf8_in_unchecked.rs deleted file mode 100644 index 3dc096d3197f..000000000000 --- a/tests/ui/invalid_utf8_in_unchecked.rs +++ /dev/null @@ -1,20 +0,0 @@ -#![warn(clippy::invalid_utf8_in_unchecked)] - -fn main() { - // Valid - unsafe { - std::str::from_utf8_unchecked(&[99, 108, 105, 112, 112, 121]); - std::str::from_utf8_unchecked(&[b'c', b'l', b'i', b'p', b'p', b'y']); - std::str::from_utf8_unchecked(b"clippy"); - - let x = 0xA0; - std::str::from_utf8_unchecked(&[0xC0, x]); - } - - // Invalid - unsafe { - std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); - std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); - std::str::from_utf8_unchecked(b"cl\x82ippy"); - } -} diff --git a/tests/ui/invalid_utf8_in_unchecked.stderr b/tests/ui/invalid_utf8_in_unchecked.stderr deleted file mode 100644 index c89cd2758ee9..000000000000 --- a/tests/ui/invalid_utf8_in_unchecked.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error: non UTF-8 literal in `std::str::from_utf8_unchecked` - --> $DIR/invalid_utf8_in_unchecked.rs:16:9 - | -LL | std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `-D clippy::invalid-utf8-in-unchecked` implied by `-D warnings` - -error: non UTF-8 literal in `std::str::from_utf8_unchecked` - --> $DIR/invalid_utf8_in_unchecked.rs:17:9 - | -LL | std::str::from_utf8_unchecked(&[b'c', b'l', b'/x82', b'i', b'p', b'p', b'y']); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: non UTF-8 literal in `std::str::from_utf8_unchecked` - --> $DIR/invalid_utf8_in_unchecked.rs:18:9 - | -LL | std::str::from_utf8_unchecked(b"cl/x82ippy"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors - diff --git a/tests/ui/is_digit_ascii_radix.fixed b/tests/ui/is_digit_ascii_radix.fixed index c0ba647d7079..bc43303a680d 100644 --- a/tests/ui/is_digit_ascii_radix.fixed +++ b/tests/ui/is_digit_ascii_radix.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::is_digit_ascii_radix)] diff --git a/tests/ui/is_digit_ascii_radix.rs b/tests/ui/is_digit_ascii_radix.rs index 68e3f3243d96..93cba5c8e4e5 100644 --- a/tests/ui/is_digit_ascii_radix.rs +++ b/tests/ui/is_digit_ascii_radix.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::is_digit_ascii_radix)] diff --git a/tests/ui/issue-111399.rs b/tests/ui/issue-111399.rs new file mode 100644 index 000000000000..b65e6c7261a5 --- /dev/null +++ b/tests/ui/issue-111399.rs @@ -0,0 +1,13 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// Check that rustc doesn't crash on the trait bound `Self::Ty: std::marker::Freeze`. + +pub struct Struct; + +impl Struct { + pub type Ty = usize; + pub const CT: Self::Ty = 42; +} + +fn main() {} diff --git a/tests/ui/issue-3145.rs b/tests/ui/issue-3145.rs index 586d13647d15..0b07de1144ce 100644 --- a/tests/ui/issue-3145.rs +++ b/tests/ui/issue-3145.rs @@ -1,3 +1,3 @@ fn main() { - println!("{}" a); //~ERROR expected `,`, found `a` + println!("{}" a); //~ERROR: expected `,`, found `a` } diff --git a/tests/ui/issue-3145.stderr b/tests/ui/issue-3145.stderr index a35032aa150d..d7c2c88a2047 100644 --- a/tests/ui/issue-3145.stderr +++ b/tests/ui/issue-3145.stderr @@ -1,7 +1,7 @@ error: expected `,`, found `a` --> $DIR/issue-3145.rs:2:19 | -LL | println!("{}" a); //~ERROR expected `,`, found `a` +LL | println!("{}" a); | ^ expected `,` error: aborting due to previous error diff --git a/tests/ui/issue-7447.rs b/tests/ui/issue-7447.rs index fdb77f322579..de4362c4df70 100644 --- a/tests/ui/issue-7447.rs +++ b/tests/ui/issue-7447.rs @@ -1,4 +1,7 @@ -use std::{borrow::Cow, collections::BTreeMap, marker::PhantomData, sync::Arc}; +use std::borrow::Cow; +use std::collections::BTreeMap; +use std::marker::PhantomData; +use std::sync::Arc; fn byte_view<'a>(s: &'a ByteView<'_>) -> BTreeMap<&'a str, ByteView<'a>> { panic!() diff --git a/tests/ui/issue-7447.stderr b/tests/ui/issue-7447.stderr index 8d8c29f13858..7a113740c6a4 100644 --- a/tests/ui/issue-7447.stderr +++ b/tests/ui/issue-7447.stderr @@ -1,5 +1,5 @@ error: sub-expression diverges - --> $DIR/issue-7447.rs:23:15 + --> $DIR/issue-7447.rs:26:15 | LL | byte_view(panic!()); | ^^^^^^^^ @@ -8,7 +8,7 @@ LL | byte_view(panic!()); = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error: sub-expression diverges - --> $DIR/issue-7447.rs:24:19 + --> $DIR/issue-7447.rs:27:19 | LL | group_entries(panic!()); | ^^^^^^^^ diff --git a/tests/ui/issue_2356.fixed b/tests/ui/issue_2356.fixed index a73ee0fb2e59..a69f5ebdc08c 100644 --- a/tests/ui/issue_2356.fixed +++ b/tests/ui/issue_2356.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::while_let_on_iterator)] #![allow(unused_mut)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/issue_2356.rs b/tests/ui/issue_2356.rs index 9dd9069609b1..50e1bce1f8c9 100644 --- a/tests/ui/issue_2356.rs +++ b/tests/ui/issue_2356.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::while_let_on_iterator)] #![allow(unused_mut)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/issue_4266.stderr b/tests/ui/issue_4266.stderr index fd553aa4538a..5b60646ef21d 100644 --- a/tests/ui/issue_4266.stderr +++ b/tests/ui/issue_4266.stderr @@ -1,16 +1,16 @@ error: the following explicit lifetimes could be elided: 'a - --> $DIR/issue_4266.rs:4:1 + --> $DIR/issue_4266.rs:4:16 | LL | async fn sink1<'a>(_: &'a str) {} // lint - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | = note: `-D clippy::needless-lifetimes` implied by `-D warnings` error: the following explicit lifetimes could be elided: 'a - --> $DIR/issue_4266.rs:8:1 + --> $DIR/issue_4266.rs:8:21 | LL | async fn one_to_one<'a>(s: &'a str) -> &'a str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ error: methods called `new` usually take no `self` --> $DIR/issue_4266.rs:28:22 diff --git a/tests/ui/items_after_test_module/auxiliary/tests.rs b/tests/ui/items_after_test_module/auxiliary/tests.rs new file mode 100644 index 000000000000..f328e4d9d04c --- /dev/null +++ b/tests/ui/items_after_test_module/auxiliary/tests.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/tests/ui/items_after_test_module/block_module.rs b/tests/ui/items_after_test_module/block_module.rs new file mode 100644 index 000000000000..3174932c3ff8 --- /dev/null +++ b/tests/ui/items_after_test_module/block_module.rs @@ -0,0 +1,60 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@compile-flags: --test +======= +======= +//@compile-flags: --test +======= +<<<<<<< HEAD +<<<<<<< HEAD +//@compile-flags: --test +======= +>>>>>>> 4da6e7e06 (rebase attempt) +// compile-flags: --test +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= +//@compile-flags: --test +>>>>>>> 1ac8dc51b (Compact emmited lint) +<<<<<<< HEAD +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) +#![allow(unused)] +#![warn(clippy::items_after_test_module)] + +fn main() {} + +fn should_not_lint() {} + +#[allow(dead_code)] +#[allow(unused)] // Some attributes to check that span replacement is good enough +#[allow(clippy::allow_attributes)] +#[cfg(test)] +mod tests { + #[test] + fn hi() {} +} + +fn should_lint() {} + +const SHOULD_ALSO_LINT: usize = 1; +<<<<<<< HEAD +<<<<<<< HEAD +======= +======= +<<<<<<< HEAD +>>>>>>> 4da6e7e06 (rebase attempt) +<<<<<<< HEAD +======= + +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= +>>>>>>> 1ac8dc51b (Compact emmited lint) +<<<<<<< HEAD +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) +macro_rules! should_not_lint { + () => {}; +} diff --git a/tests/ui/items_after_test_module/block_module.stderr b/tests/ui/items_after_test_module/block_module.stderr new file mode 100644 index 000000000000..c9ce5d2103b1 --- /dev/null +++ b/tests/ui/items_after_test_module/block_module.stderr @@ -0,0 +1,66 @@ +<<<<<<< HEAD +<<<<<<< HEAD +======= +error: Option 'test' given more than once +======= +>>>>>>> 4da6e7e06 (rebase attempt) +<<<<<<< HEAD +<<<<<<< HEAD +error: items were found after the testing module + --> $DIR/block_module.rs:13:1 + | +LL | / mod tests { +LL | | #[test] +LL | | fn hi() {} +LL | | } +... | +LL | | () => {}; +LL | | } + | |_^ + | + = help: move the items to before the testing module was defined + = note: `-D clippy::items-after-test-module` implied by `-D warnings` + +error: aborting due to previous error +======= +error: an item was found after the testing module + --> $DIR/items_after_test_module.rs:18:1 +======= +error: items were found after the testing module + --> $DIR/items_after_test_module.rs:13:1 +>>>>>>> 1ac8dc51b (Compact emmited lint) + | +LL | / mod tests { +LL | | #[test] +LL | | fn hi() {} +LL | | } +... | +LL | | () => {}; +LL | | } + | |_^ + | + = help: move the items to before the testing module was defined + = note: `-D clippy::items-after-test-module` implied by `-D warnings` + +<<<<<<< HEAD +error: an item was found after the testing module + --> $DIR/items_after_test_module.rs:20:1 + | +LL | const SHOULD_ALSO_LINT: usize = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: move the item to before the testing module was defined + +error: aborting due to 2 previous errors +>>>>>>> 0354cee13 (Add lint `items_after_test_module`) +======= +error: aborting due to previous error +>>>>>>> 1ac8dc51b (Compact emmited lint) +<<<<<<< HEAD +======= +error: Option 'test' given more than once +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + diff --git a/tests/ui/items_after_test_module/imported_module.rs b/tests/ui/items_after_test_module/imported_module.rs new file mode 100644 index 000000000000..51ec9fb8cd66 --- /dev/null +++ b/tests/ui/items_after_test_module/imported_module.rs @@ -0,0 +1,46 @@ +//@compile-flags: --test +#![allow(unused)] +#![warn(clippy::items_after_test_module)] + +<<<<<<< HEAD +<<<<<<< HEAD +// Nothing here should lint, as `tests` is an imported module (that has no body). + +======= +>>>>>>> 273c898ae (Fix #10713 and move the tests to a subdir) +======= +// Nothing here should lint, as `tests` is an imported module (that has no body). + +>>>>>>> 395b1f5bf (Rename items + Delete `imported_module.stderr`) +fn main() {} + +fn should_not_lint() {} + +<<<<<<< HEAD +<<<<<<< HEAD +#[path = "auxiliary/tests.rs"] +#[cfg(test)] +mod tests; // Should not lint + +fn should_not_lint2() {} +<<<<<<< HEAD + +const SHOULD_ALSO_NOT_LINT: usize = 1; +======= +======= +#[path = "auxiliary/tests.rs"] +>>>>>>> 2b5820d58 (Change module import system) +#[cfg(test)] +mod tests; // Should not lint + +fn should_lint() {} + +const SHOULD_ALSO_LINT: usize = 1; +>>>>>>> 273c898ae (Fix #10713 and move the tests to a subdir) +======= + +const SHOULD_ALSO_NOT_LINT: usize = 1; +>>>>>>> 395b1f5bf (Rename items + Delete `imported_module.stderr`) +macro_rules! should_not_lint { + () => {}; +} diff --git a/tests/ui/iter_cloned_collect.fixed b/tests/ui/iter_cloned_collect.fixed index 9b8621335804..636f572a343e 100644 --- a/tests/ui/iter_cloned_collect.fixed +++ b/tests/ui/iter_cloned_collect.fixed @@ -1,9 +1,9 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] +#![allow(clippy::useless_vec)] -use std::collections::HashSet; -use std::collections::VecDeque; +use std::collections::{HashSet, VecDeque}; fn main() { let v = [1, 2, 3, 4, 5]; diff --git a/tests/ui/iter_cloned_collect.rs b/tests/ui/iter_cloned_collect.rs index 639f50665f2a..518cb75affe5 100644 --- a/tests/ui/iter_cloned_collect.rs +++ b/tests/ui/iter_cloned_collect.rs @@ -1,9 +1,9 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] +#![allow(clippy::useless_vec)] -use std::collections::HashSet; -use std::collections::VecDeque; +use std::collections::{HashSet, VecDeque}; fn main() { let v = [1, 2, 3, 4, 5]; diff --git a/tests/ui/iter_count.fixed b/tests/ui/iter_count.fixed index 90a6eef75261..b6208201409f 100644 --- a/tests/ui/iter_count.fixed +++ b/tests/ui/iter_count.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::iter_count)] #![allow( @@ -7,7 +7,8 @@ array_into_iter, unused_mut, clippy::into_iter_on_ref, - clippy::unnecessary_operation + clippy::unnecessary_operation, + clippy::useless_vec )] extern crate option_helpers; diff --git a/tests/ui/iter_count.rs b/tests/ui/iter_count.rs index 6681a480a28c..fb2161312098 100644 --- a/tests/ui/iter_count.rs +++ b/tests/ui/iter_count.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::iter_count)] #![allow( @@ -7,7 +7,8 @@ array_into_iter, unused_mut, clippy::into_iter_on_ref, - clippy::unnecessary_operation + clippy::unnecessary_operation, + clippy::useless_vec )] extern crate option_helpers; diff --git a/tests/ui/iter_count.stderr b/tests/ui/iter_count.stderr index 2e3d7fc35de9..f9aee0b7846d 100644 --- a/tests/ui/iter_count.stderr +++ b/tests/ui/iter_count.stderr @@ -1,5 +1,5 @@ error: called `.iter().count()` on a `slice` - --> $DIR/iter_count.rs:54:6 + --> $DIR/iter_count.rs:55:6 | LL | &vec[..].iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()` @@ -7,145 +7,145 @@ LL | &vec[..].iter().count(); = note: `-D clippy::iter-count` implied by `-D warnings` error: called `.iter().count()` on a `Vec` - --> $DIR/iter_count.rs:55:5 + --> $DIR/iter_count.rs:56:5 | LL | vec.iter().count(); | ^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` error: called `.iter().count()` on a `slice` - --> $DIR/iter_count.rs:56:5 + --> $DIR/iter_count.rs:57:5 | LL | boxed_slice.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice.len()` error: called `.iter().count()` on a `VecDeque` - --> $DIR/iter_count.rs:57:5 + --> $DIR/iter_count.rs:58:5 | LL | vec_deque.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` error: called `.iter().count()` on a `HashSet` - --> $DIR/iter_count.rs:58:5 + --> $DIR/iter_count.rs:59:5 | LL | hash_set.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()` error: called `.iter().count()` on a `HashMap` - --> $DIR/iter_count.rs:59:5 + --> $DIR/iter_count.rs:60:5 | LL | hash_map.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()` error: called `.iter().count()` on a `BTreeMap` - --> $DIR/iter_count.rs:60:5 + --> $DIR/iter_count.rs:61:5 | LL | b_tree_map.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()` error: called `.iter().count()` on a `BTreeSet` - --> $DIR/iter_count.rs:61:5 + --> $DIR/iter_count.rs:62:5 | LL | b_tree_set.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_set.len()` error: called `.iter().count()` on a `LinkedList` - --> $DIR/iter_count.rs:62:5 + --> $DIR/iter_count.rs:63:5 | LL | linked_list.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()` error: called `.iter().count()` on a `BinaryHeap` - --> $DIR/iter_count.rs:63:5 + --> $DIR/iter_count.rs:64:5 | LL | binary_heap.iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `binary_heap.len()` error: called `.iter_mut().count()` on a `Vec` - --> $DIR/iter_count.rs:65:5 + --> $DIR/iter_count.rs:66:5 | LL | vec.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` error: called `.iter_mut().count()` on a `slice` - --> $DIR/iter_count.rs:66:6 + --> $DIR/iter_count.rs:67:6 | LL | &vec[..].iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()` error: called `.iter_mut().count()` on a `VecDeque` - --> $DIR/iter_count.rs:67:5 + --> $DIR/iter_count.rs:68:5 | LL | vec_deque.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` error: called `.iter_mut().count()` on a `HashMap` - --> $DIR/iter_count.rs:68:5 + --> $DIR/iter_count.rs:69:5 | LL | hash_map.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()` error: called `.iter_mut().count()` on a `BTreeMap` - --> $DIR/iter_count.rs:69:5 + --> $DIR/iter_count.rs:70:5 | LL | b_tree_map.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()` error: called `.iter_mut().count()` on a `LinkedList` - --> $DIR/iter_count.rs:70:5 + --> $DIR/iter_count.rs:71:5 | LL | linked_list.iter_mut().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()` error: called `.into_iter().count()` on a `slice` - --> $DIR/iter_count.rs:72:6 + --> $DIR/iter_count.rs:73:6 | LL | &vec[..].into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()` error: called `.into_iter().count()` on a `Vec` - --> $DIR/iter_count.rs:73:5 + --> $DIR/iter_count.rs:74:5 | LL | vec.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()` error: called `.into_iter().count()` on a `VecDeque` - --> $DIR/iter_count.rs:74:5 + --> $DIR/iter_count.rs:75:5 | LL | vec_deque.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()` error: called `.into_iter().count()` on a `HashSet` - --> $DIR/iter_count.rs:75:5 + --> $DIR/iter_count.rs:76:5 | LL | hash_set.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()` error: called `.into_iter().count()` on a `HashMap` - --> $DIR/iter_count.rs:76:5 + --> $DIR/iter_count.rs:77:5 | LL | hash_map.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()` error: called `.into_iter().count()` on a `BTreeMap` - --> $DIR/iter_count.rs:77:5 + --> $DIR/iter_count.rs:78:5 | LL | b_tree_map.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()` error: called `.into_iter().count()` on a `BTreeSet` - --> $DIR/iter_count.rs:78:5 + --> $DIR/iter_count.rs:79:5 | LL | b_tree_set.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_set.len()` error: called `.into_iter().count()` on a `LinkedList` - --> $DIR/iter_count.rs:79:5 + --> $DIR/iter_count.rs:80:5 | LL | linked_list.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()` error: called `.into_iter().count()` on a `BinaryHeap` - --> $DIR/iter_count.rs:80:5 + --> $DIR/iter_count.rs:81:5 | LL | binary_heap.into_iter().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `binary_heap.len()` diff --git a/tests/ui/iter_kv_map.fixed b/tests/ui/iter_kv_map.fixed index f2a4c284cb16..64201b553fdd 100644 --- a/tests/ui/iter_kv_map.fixed +++ b/tests/ui/iter_kv_map.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_kv_map)] #![allow(unused_mut, clippy::redundant_clone, clippy::suspicious_map, clippy::map_identity)] diff --git a/tests/ui/iter_kv_map.rs b/tests/ui/iter_kv_map.rs index ad6564df4084..ec0231ba5727 100644 --- a/tests/ui/iter_kv_map.rs +++ b/tests/ui/iter_kv_map.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_kv_map)] #![allow(unused_mut, clippy::redundant_clone, clippy::suspicious_map, clippy::map_identity)] diff --git a/tests/ui/iter_next_loop.rs b/tests/ui/iter_next_loop.rs new file mode 100644 index 000000000000..548b799de44e --- /dev/null +++ b/tests/ui/iter_next_loop.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, unused, for_loops_over_fallibles)] +#![warn(clippy::iter_next_loop)] + +fn main() { + let x = [1, 2, 3, 4]; + for _ in vec.iter().next() {} + + struct Unrelated(&'static [u8]); + impl Unrelated { + fn next(&self) -> std::slice::Iter { + self.0.iter() + } + } + let u = Unrelated(&[0]); + for _v in u.next() {} // no error +} diff --git a/tests/ui/iter_next_loop.stderr b/tests/ui/iter_next_loop.stderr new file mode 100644 index 000000000000..5bba0e635bba --- /dev/null +++ b/tests/ui/iter_next_loop.stderr @@ -0,0 +1,9 @@ +error[E0423]: expected value, found macro `vec` + --> $DIR/iter_next_loop.rs:6:14 + | +LL | for _ in vec.iter().next() {} + | ^^^ not a value + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/iter_next_slice.fixed b/tests/ui/iter_next_slice.fixed index f612d26aaabc..702edccdbad0 100644 --- a/tests/ui/iter_next_slice.fixed +++ b/tests/ui/iter_next_slice.fixed @@ -1,5 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_next_slice)] +#![allow(clippy::useless_vec)] fn main() { // test code goes here diff --git a/tests/ui/iter_next_slice.rs b/tests/ui/iter_next_slice.rs index 5195f1c86675..30bfc72de179 100644 --- a/tests/ui/iter_next_slice.rs +++ b/tests/ui/iter_next_slice.rs @@ -1,5 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_next_slice)] +#![allow(clippy::useless_vec)] fn main() { // test code goes here diff --git a/tests/ui/iter_next_slice.stderr b/tests/ui/iter_next_slice.stderr index d8b89061ff89..0db8201a1325 100644 --- a/tests/ui/iter_next_slice.stderr +++ b/tests/ui/iter_next_slice.stderr @@ -1,5 +1,5 @@ error: using `.iter().next()` on an array - --> $DIR/iter_next_slice.rs:9:13 + --> $DIR/iter_next_slice.rs:10:13 | LL | let _ = s.iter().next(); | ^^^^^^^^^^^^^^^ help: try calling: `s.first()` @@ -7,19 +7,19 @@ LL | let _ = s.iter().next(); = note: `-D clippy::iter-next-slice` implied by `-D warnings` error: using `.iter().next()` on a Slice without end index - --> $DIR/iter_next_slice.rs:12:13 + --> $DIR/iter_next_slice.rs:13:13 | LL | let _ = s[2..].iter().next(); | ^^^^^^^^^^^^^^^^^^^^ help: try calling: `s.get(2)` error: using `.iter().next()` on a Slice without end index - --> $DIR/iter_next_slice.rs:15:13 + --> $DIR/iter_next_slice.rs:16:13 | LL | let _ = v[5..].iter().next(); | ^^^^^^^^^^^^^^^^^^^^ help: try calling: `v.get(5)` error: using `.iter().next()` on an array - --> $DIR/iter_next_slice.rs:18:13 + --> $DIR/iter_next_slice.rs:19:13 | LL | let _ = v.iter().next(); | ^^^^^^^^^^^^^^^ help: try calling: `v.first()` diff --git a/tests/ui/iter_nth.rs b/tests/ui/iter_nth.rs index 9c21dd82ee45..7c567bb81d88 100644 --- a/tests/ui/iter_nth.rs +++ b/tests/ui/iter_nth.rs @@ -1,6 +1,7 @@ -// aux-build:option_helpers.rs +//@aux-build:option_helpers.rs #![warn(clippy::iter_nth)] +#![allow(clippy::useless_vec)] #[macro_use] extern crate option_helpers; diff --git a/tests/ui/iter_nth.stderr b/tests/ui/iter_nth.stderr index a0fe353bcf75..07d80ba78a19 100644 --- a/tests/ui/iter_nth.stderr +++ b/tests/ui/iter_nth.stderr @@ -1,5 +1,13 @@ +<<<<<<< HEAD +<<<<<<< HEAD +error: called `.iter().nth()` on a `Vec` +======= error: called `.iter().nth()` on a Vec - --> $DIR/iter_nth.rs:33:23 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +error: called `.iter().nth()` on a `Vec` +>>>>>>> 242807a9c (Don't lint `iter_nth_zero` in `next`) + --> $DIR/iter_nth.rs:34:23 | LL | let bad_vec = some_vec.iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +16,7 @@ LL | let bad_vec = some_vec.iter().nth(3); = note: `-D clippy::iter-nth` implied by `-D warnings` error: called `.iter().nth()` on a slice - --> $DIR/iter_nth.rs:34:26 + --> $DIR/iter_nth.rs:35:26 | LL | let bad_slice = &some_vec[..].iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,23 +24,39 @@ LL | let bad_slice = &some_vec[..].iter().nth(3); = help: calling `.get()` is both faster and more readable error: called `.iter().nth()` on a slice - --> $DIR/iter_nth.rs:35:31 + --> $DIR/iter_nth.rs:36:31 | LL | let bad_boxed_slice = boxed_slice.iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: calling `.get()` is both faster and more readable +<<<<<<< HEAD +<<<<<<< HEAD +error: called `.iter().nth()` on a `VecDeque` +======= error: called `.iter().nth()` on a VecDeque - --> $DIR/iter_nth.rs:36:29 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +error: called `.iter().nth()` on a `VecDeque` +>>>>>>> 242807a9c (Don't lint `iter_nth_zero` in `next`) + --> $DIR/iter_nth.rs:37:29 | LL | let bad_vec_deque = some_vec_deque.iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: calling `.get()` is both faster and more readable +<<<<<<< HEAD +<<<<<<< HEAD +error: called `.iter_mut().nth()` on a `Vec` +======= error: called `.iter_mut().nth()` on a Vec - --> $DIR/iter_nth.rs:41:23 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +error: called `.iter_mut().nth()` on a `Vec` +>>>>>>> 242807a9c (Don't lint `iter_nth_zero` in `next`) + --> $DIR/iter_nth.rs:42:23 | LL | let bad_vec = some_vec.iter_mut().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,15 +64,23 @@ LL | let bad_vec = some_vec.iter_mut().nth(3); = help: calling `.get_mut()` is both faster and more readable error: called `.iter_mut().nth()` on a slice - --> $DIR/iter_nth.rs:44:26 + --> $DIR/iter_nth.rs:45:26 | LL | let bad_slice = &some_vec[..].iter_mut().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: calling `.get_mut()` is both faster and more readable +<<<<<<< HEAD +<<<<<<< HEAD +error: called `.iter_mut().nth()` on a `VecDeque` +======= error: called `.iter_mut().nth()` on a VecDeque - --> $DIR/iter_nth.rs:47:29 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +error: called `.iter_mut().nth()` on a `VecDeque` +>>>>>>> 242807a9c (Don't lint `iter_nth_zero` in `next`) + --> $DIR/iter_nth.rs:48:29 | LL | let bad_vec_deque = some_vec_deque.iter_mut().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/iter_nth_zero.fixed b/tests/ui/iter_nth_zero.fixed index f23671c26e4c..91f4a7ba0d2f 100644 --- a/tests/ui/iter_nth_zero.fixed +++ b/tests/ui/iter_nth_zero.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_nth_zero)] use std::collections::HashSet; @@ -29,3 +29,18 @@ fn main() { let mut iter2 = s3.iter(); let _unwrapped = iter2.next().unwrap(); } + +struct Issue9820; + +impl Iterator for Issue9820 { + type Item = (); + + fn nth(&mut self, _n: usize) -> Option { + todo!() + } + + // Don't lint in implementations of `next`, as calling `next` in `next` is incorrect + fn next(&mut self) -> Option { + self.nth(0) + } +} diff --git a/tests/ui/iter_nth_zero.rs b/tests/ui/iter_nth_zero.rs index 7c968d498457..160a895bb7b4 100644 --- a/tests/ui/iter_nth_zero.rs +++ b/tests/ui/iter_nth_zero.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_nth_zero)] use std::collections::HashSet; @@ -29,3 +29,18 @@ fn main() { let mut iter2 = s3.iter(); let _unwrapped = iter2.nth(0).unwrap(); } + +struct Issue9820; + +impl Iterator for Issue9820 { + type Item = (); + + fn nth(&mut self, _n: usize) -> Option { + todo!() + } + + // Don't lint in implementations of `next`, as calling `next` in `next` is incorrect + fn next(&mut self) -> Option { + self.nth(0) + } +} diff --git a/tests/ui/iter_on_empty_collections.fixed b/tests/ui/iter_on_empty_collections.fixed index bd9b07aefbfb..4616f0cdc45e 100644 --- a/tests/ui/iter_on_empty_collections.fixed +++ b/tests/ui/iter_on_empty_collections.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_on_empty_collections)] #![allow(clippy::iter_next_slice, clippy::redundant_clone)] diff --git a/tests/ui/iter_on_empty_collections.rs b/tests/ui/iter_on_empty_collections.rs index e15ba94bd465..81cc7265e11e 100644 --- a/tests/ui/iter_on_empty_collections.rs +++ b/tests/ui/iter_on_empty_collections.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_on_empty_collections)] #![allow(clippy::iter_next_slice, clippy::redundant_clone)] diff --git a/tests/ui/iter_on_single_items.fixed b/tests/ui/iter_on_single_items.fixed index 1fa4b03641bc..80dbe454b470 100644 --- a/tests/ui/iter_on_single_items.fixed +++ b/tests/ui/iter_on_single_items.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_on_single_items)] #![allow(clippy::iter_next_slice, clippy::redundant_clone)] diff --git a/tests/ui/iter_on_single_items.rs b/tests/ui/iter_on_single_items.rs index ea96d8066c56..71c8c7a3f94c 100644 --- a/tests/ui/iter_on_single_items.rs +++ b/tests/ui/iter_on_single_items.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_on_single_items)] #![allow(clippy::iter_next_slice, clippy::redundant_clone)] diff --git a/tests/ui/iter_overeager_cloned.fixed b/tests/ui/iter_overeager_cloned.fixed index c100705d0178..2874513c049b 100644 --- a/tests/ui/iter_overeager_cloned.fixed +++ b/tests/ui/iter_overeager_cloned.fixed @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)] -#![allow(dead_code, clippy::let_unit_value)] +#![allow(dead_code, clippy::let_unit_value, clippy::useless_vec)] fn main() { let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()]; diff --git a/tests/ui/iter_overeager_cloned.rs b/tests/ui/iter_overeager_cloned.rs index 2caa88020662..26f39734a512 100644 --- a/tests/ui/iter_overeager_cloned.rs +++ b/tests/ui/iter_overeager_cloned.rs @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)] -#![allow(dead_code, clippy::let_unit_value)] +#![allow(dead_code, clippy::let_unit_value, clippy::useless_vec)] fn main() { let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()]; diff --git a/tests/ui/iter_overeager_cloned.stderr b/tests/ui/iter_overeager_cloned.stderr index dcae7cecd33e..eaac48be8809 100644 --- a/tests/ui/iter_overeager_cloned.stderr +++ b/tests/ui/iter_overeager_cloned.stderr @@ -4,7 +4,7 @@ error: unnecessarily eager cloning of iterator items LL | let _: Option = vec.iter().cloned().last(); | ^^^^^^^^^^---------------- | | - | help: try this: `.last().cloned()` + | help: try: `.last().cloned()` | = note: `-D clippy::iter-overeager-cloned` implied by `-D warnings` @@ -14,7 +14,7 @@ error: unnecessarily eager cloning of iterator items LL | let _: Option = vec.iter().chain(vec.iter()).cloned().next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------- | | - | help: try this: `.next().cloned()` + | help: try: `.next().cloned()` error: unneeded cloning of iterator items --> $DIR/iter_overeager_cloned.rs:12:20 @@ -22,7 +22,7 @@ error: unneeded cloning of iterator items LL | let _: usize = vec.iter().filter(|x| x == &"2").cloned().count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------- | | - | help: try this: `.count()` + | help: try: `.count()` | = note: `-D clippy::redundant-clone` implied by `-D warnings` @@ -32,7 +32,7 @@ error: unnecessarily eager cloning of iterator items LL | let _: Vec<_> = vec.iter().cloned().take(2).collect(); | ^^^^^^^^^^----------------- | | - | help: try this: `.take(2).cloned()` + | help: try: `.take(2).cloned()` error: unnecessarily eager cloning of iterator items --> $DIR/iter_overeager_cloned.rs:16:21 @@ -40,7 +40,7 @@ error: unnecessarily eager cloning of iterator items LL | let _: Vec<_> = vec.iter().cloned().skip(2).collect(); | ^^^^^^^^^^----------------- | | - | help: try this: `.skip(2).cloned()` + | help: try: `.skip(2).cloned()` error: unnecessarily eager cloning of iterator items --> $DIR/iter_overeager_cloned.rs:18:13 @@ -48,7 +48,7 @@ error: unnecessarily eager cloning of iterator items LL | let _ = vec.iter().filter(|x| x == &"2").cloned().nth(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------- | | - | help: try this: `.nth(2).cloned()` + | help: try: `.nth(2).cloned()` error: unnecessarily eager cloning of iterator items --> $DIR/iter_overeager_cloned.rs:20:13 @@ -60,7 +60,7 @@ LL | | .cloned() LL | | .flatten(); | |__________________^ | -help: try this +help: try | LL ~ .iter() LL ~ .flatten().cloned(); diff --git a/tests/ui/iter_skip_next.fixed b/tests/ui/iter_skip_next.fixed index d56d623b5268..b888d965e8d7 100644 --- a/tests/ui/iter_skip_next.fixed +++ b/tests/ui/iter_skip_next.fixed @@ -1,9 +1,10 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::iter_skip_next)] #![allow(clippy::disallowed_names)] #![allow(clippy::iter_nth)] +#![allow(clippy::useless_vec)] #![allow(unused_mut, dead_code)] extern crate option_helpers; diff --git a/tests/ui/iter_skip_next.rs b/tests/ui/iter_skip_next.rs index 3ec5d1b82142..e44efdebc471 100644 --- a/tests/ui/iter_skip_next.rs +++ b/tests/ui/iter_skip_next.rs @@ -1,9 +1,10 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::iter_skip_next)] #![allow(clippy::disallowed_names)] #![allow(clippy::iter_nth)] +#![allow(clippy::useless_vec)] #![allow(unused_mut, dead_code)] extern crate option_helpers; diff --git a/tests/ui/iter_skip_next.stderr b/tests/ui/iter_skip_next.stderr index ca6970b27f16..4ee26e088ce3 100644 --- a/tests/ui/iter_skip_next.stderr +++ b/tests/ui/iter_skip_next.stderr @@ -1,5 +1,5 @@ error: called `skip(..).next()` on an iterator - --> $DIR/iter_skip_next.rs:16:28 + --> $DIR/iter_skip_next.rs:17:28 | LL | let _ = some_vec.iter().skip(42).next(); | ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(42)` @@ -7,37 +7,37 @@ LL | let _ = some_vec.iter().skip(42).next(); = note: `-D clippy::iter-skip-next` implied by `-D warnings` error: called `skip(..).next()` on an iterator - --> $DIR/iter_skip_next.rs:17:36 + --> $DIR/iter_skip_next.rs:18:36 | LL | let _ = some_vec.iter().cycle().skip(42).next(); | ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(42)` error: called `skip(..).next()` on an iterator - --> $DIR/iter_skip_next.rs:18:20 + --> $DIR/iter_skip_next.rs:19:20 | LL | let _ = (1..10).skip(10).next(); | ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(10)` error: called `skip(..).next()` on an iterator - --> $DIR/iter_skip_next.rs:19:33 + --> $DIR/iter_skip_next.rs:20:33 | LL | let _ = &some_vec[..].iter().skip(3).next(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(3)` error: called `skip(..).next()` on an iterator - --> $DIR/iter_skip_next.rs:27:26 + --> $DIR/iter_skip_next.rs:28:26 | LL | let _: Vec<&str> = sp.skip(1).next().unwrap().split(' ').collect(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)` error: called `skip(..).next()` on an iterator - --> $DIR/iter_skip_next.rs:29:29 + --> $DIR/iter_skip_next.rs:30:29 | LL | let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)` error: called `skip(..).next()` on an iterator - --> $DIR/iter_skip_next.rs:35:29 + --> $DIR/iter_skip_next.rs:36:29 | LL | let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)` diff --git a/tests/ui/iter_with_drain.fixed b/tests/ui/iter_with_drain.fixed index 0330d5549264..7a8c67701010 100644 --- a/tests/ui/iter_with_drain.fixed +++ b/tests/ui/iter_with_drain.fixed @@ -1,8 +1,8 @@ -// run-rustfix +//@run-rustfix // will emits unused mut warnings after fixing #![allow(unused_mut)] // will emits needless collect warnings after fixing -#![allow(clippy::needless_collect)] +#![allow(clippy::needless_collect, clippy::drain_collect)] #![warn(clippy::iter_with_drain)] use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; diff --git a/tests/ui/iter_with_drain.rs b/tests/ui/iter_with_drain.rs index 993936fb8de3..cf3a935c349a 100644 --- a/tests/ui/iter_with_drain.rs +++ b/tests/ui/iter_with_drain.rs @@ -1,8 +1,8 @@ -// run-rustfix +//@run-rustfix // will emits unused mut warnings after fixing #![allow(unused_mut)] // will emits needless collect warnings after fixing -#![allow(clippy::needless_collect)] +#![allow(clippy::needless_collect, clippy::drain_collect)] #![warn(clippy::iter_with_drain)] use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; diff --git a/tests/ui/iter_with_drain.stderr b/tests/ui/iter_with_drain.stderr index aa394439fa62..bfaed29a099c 100644 --- a/tests/ui/iter_with_drain.stderr +++ b/tests/ui/iter_with_drain.stderr @@ -2,7 +2,7 @@ error: `drain(..)` used on a `Vec` --> $DIR/iter_with_drain.rs:11:34 | LL | let mut a: BinaryHeap<_> = a.drain(..).collect(); - | ^^^^^^^^^ help: try this: `into_iter()` + | ^^^^^^^^^ help: try: `into_iter()` | = note: `-D clippy::iter-with-drain` implied by `-D warnings` @@ -10,31 +10,31 @@ error: `drain(..)` used on a `VecDeque` --> $DIR/iter_with_drain.rs:14:27 | LL | let mut a: Vec<_> = a.drain(..).collect(); - | ^^^^^^^^^ help: try this: `into_iter()` + | ^^^^^^^^^ help: try: `into_iter()` error: `drain(..)` used on a `Vec` --> $DIR/iter_with_drain.rs:15:34 | LL | let mut a: HashMap<_, _> = a.drain(..).map(|x| (x.clone(), x)).collect(); - | ^^^^^^^^^ help: try this: `into_iter()` + | ^^^^^^^^^ help: try: `into_iter()` error: `drain(..)` used on a `Vec` --> $DIR/iter_with_drain.rs:21:34 | LL | let mut a: BinaryHeap<_> = a.drain(0..).collect(); - | ^^^^^^^^^^ help: try this: `into_iter()` + | ^^^^^^^^^^ help: try: `into_iter()` error: `drain(..)` used on a `VecDeque` --> $DIR/iter_with_drain.rs:24:27 | LL | let mut a: Vec<_> = a.drain(..a.len()).collect(); - | ^^^^^^^^^^^^^^^^ help: try this: `into_iter()` + | ^^^^^^^^^^^^^^^^ help: try: `into_iter()` error: `drain(..)` used on a `Vec` --> $DIR/iter_with_drain.rs:25:34 | LL | let mut a: HashMap<_, _> = a.drain(0..a.len()).map(|x| (x.clone(), x)).collect(); - | ^^^^^^^^^^^^^^^^^ help: try this: `into_iter()` + | ^^^^^^^^^^^^^^^^^ help: try: `into_iter()` error: aborting due to 6 previous errors diff --git a/tests/ui/iterator_step_by_zero.rs b/tests/ui/iterator_step_by_zero.rs index 13d1cfd42818..33ec78e9a416 100644 --- a/tests/ui/iterator_step_by_zero.rs +++ b/tests/ui/iterator_step_by_zero.rs @@ -1,3 +1,4 @@ +#![allow(clippy::useless_vec)] #[warn(clippy::iterator_step_by_zero)] fn main() { let _ = vec!["A", "B", "B"].iter().step_by(0); diff --git a/tests/ui/iterator_step_by_zero.stderr b/tests/ui/iterator_step_by_zero.stderr index d792aea11dfa..b470e2ed2eab 100644 --- a/tests/ui/iterator_step_by_zero.stderr +++ b/tests/ui/iterator_step_by_zero.stderr @@ -1,5 +1,5 @@ error: `Iterator::step_by(0)` will panic at runtime - --> $DIR/iterator_step_by_zero.rs:3:13 + --> $DIR/iterator_step_by_zero.rs:4:13 | LL | let _ = vec!["A", "B", "B"].iter().step_by(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,37 +7,37 @@ LL | let _ = vec!["A", "B", "B"].iter().step_by(0); = note: `-D clippy::iterator-step-by-zero` implied by `-D warnings` error: `Iterator::step_by(0)` will panic at runtime - --> $DIR/iterator_step_by_zero.rs:4:13 + --> $DIR/iterator_step_by_zero.rs:5:13 | LL | let _ = "XXX".chars().step_by(0); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> $DIR/iterator_step_by_zero.rs:5:13 + --> $DIR/iterator_step_by_zero.rs:6:13 | LL | let _ = (0..1).step_by(0); | ^^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> $DIR/iterator_step_by_zero.rs:14:13 + --> $DIR/iterator_step_by_zero.rs:15:13 | LL | let _ = (1..).step_by(0); | ^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> $DIR/iterator_step_by_zero.rs:15:13 + --> $DIR/iterator_step_by_zero.rs:16:13 | LL | let _ = (1..=2).step_by(0); | ^^^^^^^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> $DIR/iterator_step_by_zero.rs:18:13 + --> $DIR/iterator_step_by_zero.rs:19:13 | LL | let _ = x.step_by(0); | ^^^^^^^^^^^^ error: `Iterator::step_by(0)` will panic at runtime - --> $DIR/iterator_step_by_zero.rs:22:13 + --> $DIR/iterator_step_by_zero.rs:23:13 | LL | let _ = v1.iter().step_by(2 / 3); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/path_join_correction.rs b/tests/ui/join_absolute_path.fixed similarity index 90% rename from tests/ui/path_join_correction.rs rename to tests/ui/join_absolute_path.fixed index c0f98ff2fd6a..766dedbb1877 100644 --- a/tests/ui/path_join_correction.rs +++ b/tests/ui/join_absolute_path.fixed @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] -#![warn(clippy::path_join_correction)] +#![warn(clippy::join_absolute_paths)] use std::path::Path; fn main() { diff --git a/tests/ui/path_join_correction.fixed b/tests/ui/join_absolute_paths.rs similarity index 90% rename from tests/ui/path_join_correction.fixed rename to tests/ui/join_absolute_paths.rs index c0f98ff2fd6a..766dedbb1877 100644 --- a/tests/ui/path_join_correction.fixed +++ b/tests/ui/join_absolute_paths.rs @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] -#![warn(clippy::path_join_correction)] +#![warn(clippy::join_absolute_paths)] use std::path::Path; fn main() { diff --git a/tests/ui/large_const_arrays.fixed b/tests/ui/large_const_arrays.fixed index c5af07c8a172..f7ce6fbe6bb4 100644 --- a/tests/ui/large_const_arrays.fixed +++ b/tests/ui/large_const_arrays.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::large_const_arrays)] #![allow(dead_code)] diff --git a/tests/ui/large_const_arrays.rs b/tests/ui/large_const_arrays.rs index a160b9f8ad5b..002ac77ddda9 100644 --- a/tests/ui/large_const_arrays.rs +++ b/tests/ui/large_const_arrays.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::large_const_arrays)] #![allow(dead_code)] diff --git a/tests/ui/large_digit_groups.fixed b/tests/ui/large_digit_groups.fixed index ea18dac06833..f42fcd96d795 100644 --- a/tests/ui/large_digit_groups.fixed +++ b/tests/ui/large_digit_groups.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::large_digit_groups)] fn main() { diff --git a/tests/ui/large_digit_groups.rs b/tests/ui/large_digit_groups.rs index ac116d5dbda1..3db9da6a3a58 100644 --- a/tests/ui/large_digit_groups.rs +++ b/tests/ui/large_digit_groups.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::large_digit_groups)] fn main() { diff --git a/tests/ui/large_enum_variant.rs b/tests/ui/large_enum_variant.rs index f09f8ae0ccc3..7bea57c1f9b1 100644 --- a/tests/ui/large_enum_variant.rs +++ b/tests/ui/large_enum_variant.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(dead_code)] #![allow(unused_variables)] diff --git a/tests/ui/large_futures.rs b/tests/ui/large_futures.rs index 4a8ba995da55..e0f6b3d9d3b4 100644 --- a/tests/ui/large_futures.rs +++ b/tests/ui/large_futures.rs @@ -1,5 +1,6 @@ #![feature(generators)] #![warn(clippy::large_futures)] +#![allow(clippy::never_loop)] #![allow(clippy::future_not_send)] #![allow(clippy::manual_async_fn)] diff --git a/tests/ui/large_futures.stderr b/tests/ui/large_futures.stderr index 67e0fceff6ef..5bcf054884e4 100644 --- a/tests/ui/large_futures.stderr +++ b/tests/ui/large_futures.stderr @@ -1,5 +1,5 @@ error: large future with a size of 16385 bytes - --> $DIR/large_futures.rs:10:9 + --> $DIR/large_futures.rs:11:9 | LL | big_fut([0u8; 1024 * 16]).await; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(big_fut([0u8; 1024 * 16]))` @@ -7,37 +7,37 @@ LL | big_fut([0u8; 1024 * 16]).await; = note: `-D clippy::large-futures` implied by `-D warnings` error: large future with a size of 16386 bytes - --> $DIR/large_futures.rs:12:5 + --> $DIR/large_futures.rs:13:5 | LL | f.await | ^ help: consider `Box::pin` on it: `Box::pin(f)` error: large future with a size of 16387 bytes - --> $DIR/large_futures.rs:16:9 + --> $DIR/large_futures.rs:17:9 | LL | wait().await; | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` error: large future with a size of 16387 bytes - --> $DIR/large_futures.rs:20:13 + --> $DIR/large_futures.rs:21:13 | LL | wait().await; | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` error: large future with a size of 65540 bytes - --> $DIR/large_futures.rs:27:5 + --> $DIR/large_futures.rs:28:5 | LL | foo().await; | ^^^^^ help: consider `Box::pin` on it: `Box::pin(foo())` error: large future with a size of 49159 bytes - --> $DIR/large_futures.rs:28:5 + --> $DIR/large_futures.rs:29:5 | LL | calls_fut(fut).await; | ^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(calls_fut(fut))` error: large future with a size of 65540 bytes - --> $DIR/large_futures.rs:40:5 + --> $DIR/large_futures.rs:41:5 | LL | / async { LL | | let x = [0i32; 1024 * 16]; @@ -56,7 +56,7 @@ LL + }) | error: large future with a size of 65540 bytes - --> $DIR/large_futures.rs:51:13 + --> $DIR/large_futures.rs:52:13 | LL | / async { LL | | let x = [0i32; 1024 * 16]; diff --git a/tests/ui/large_stack_arrays.rs b/tests/ui/large_stack_arrays.rs index 99787ffd3d39..3e9d5e6a4ca3 100644 --- a/tests/ui/large_stack_arrays.rs +++ b/tests/ui/large_stack_arrays.rs @@ -18,6 +18,19 @@ pub static DOESNOTLINT2: [u8; 512_001] = { [x; 512_001] }; +fn issue_10741() { + #[derive(Copy, Clone)] + struct Large([u32; 100_000]); + + fn build() -> Large { + Large([0; 100_000]) + } + + let _x = [build(); 3]; + + let _y = [build(), build(), build()]; +} + fn main() { let bad = ( [0u32; 20_000_000], diff --git a/tests/ui/large_stack_arrays.stderr b/tests/ui/large_stack_arrays.stderr index 24e90094982a..118d39566abe 100644 --- a/tests/ui/large_stack_arrays.stderr +++ b/tests/ui/large_stack_arrays.stderr @@ -1,14 +1,30 @@ error: allocating a local array larger than 512000 bytes - --> $DIR/large_stack_arrays.rs:23:9 + --> $DIR/large_stack_arrays.rs:29:14 + | +LL | let _x = [build(); 3]; + | ^^^^^^^^^^^^ + | + = help: consider allocating on the heap with `vec![build(); 3].into_boxed_slice()` + = note: `-D clippy::large-stack-arrays` implied by `-D warnings` + +error: allocating a local array larger than 512000 bytes + --> $DIR/large_stack_arrays.rs:31:14 + | +LL | let _y = [build(), build(), build()]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider allocating on the heap with `vec![build(), build(), build()].into_boxed_slice()` + +error: allocating a local array larger than 512000 bytes + --> $DIR/large_stack_arrays.rs:36:9 | LL | [0u32; 20_000_000], | ^^^^^^^^^^^^^^^^^^ | = help: consider allocating on the heap with `vec![0u32; 20_000_000].into_boxed_slice()` - = note: `-D clippy::large-stack-arrays` implied by `-D warnings` error: allocating a local array larger than 512000 bytes - --> $DIR/large_stack_arrays.rs:24:9 + --> $DIR/large_stack_arrays.rs:37:9 | LL | [S { data: [0; 32] }; 5000], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +32,7 @@ LL | [S { data: [0; 32] }; 5000], = help: consider allocating on the heap with `vec![S { data: [0; 32] }; 5000].into_boxed_slice()` error: allocating a local array larger than 512000 bytes - --> $DIR/large_stack_arrays.rs:25:9 + --> $DIR/large_stack_arrays.rs:38:9 | LL | [Some(""); 20_000_000], | ^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +40,7 @@ LL | [Some(""); 20_000_000], = help: consider allocating on the heap with `vec![Some(""); 20_000_000].into_boxed_slice()` error: allocating a local array larger than 512000 bytes - --> $DIR/large_stack_arrays.rs:26:9 + --> $DIR/large_stack_arrays.rs:39:9 | LL | [E::T(0); 5000], | ^^^^^^^^^^^^^^^ @@ -32,12 +48,12 @@ LL | [E::T(0); 5000], = help: consider allocating on the heap with `vec![E::T(0); 5000].into_boxed_slice()` error: allocating a local array larger than 512000 bytes - --> $DIR/large_stack_arrays.rs:27:9 + --> $DIR/large_stack_arrays.rs:40:9 | LL | [0u8; usize::MAX], | ^^^^^^^^^^^^^^^^^ | = help: consider allocating on the heap with `vec![0u8; usize::MAX].into_boxed_slice()` -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors diff --git a/tests/ui/large_stack_frames.rs b/tests/ui/large_stack_frames.rs new file mode 100644 index 000000000000..cd9d0c8a67a8 --- /dev/null +++ b/tests/ui/large_stack_frames.rs @@ -0,0 +1,44 @@ +#![allow(unused, incomplete_features)] +#![warn(clippy::large_stack_frames)] +#![feature(unsized_locals)] + +use std::hint::black_box; + +fn generic() { + let x = T::default(); + black_box(&x); +} + +fn unsized_local() { + let x: dyn std::fmt::Display = *(Box::new(1) as Box); + black_box(&x); +} + +struct ArrayDefault([u8; N]); + +impl Default for ArrayDefault { + fn default() -> Self { + Self([0; N]) + } +} + +fn many_small_arrays() { + let x = [0u8; 500_000]; + let x2 = [0u8; 500_000]; + let x3 = [0u8; 500_000]; + let x4 = [0u8; 500_000]; + let x5 = [0u8; 500_000]; + black_box((&x, &x2, &x3, &x4, &x5)); +} + +fn large_return_value() -> ArrayDefault<1_000_000> { + Default::default() +} + +fn large_fn_arg(x: ArrayDefault<1_000_000>) { + black_box(&x); +} + +fn main() { + generic::>(); +} diff --git a/tests/ui/large_stack_frames.stderr b/tests/ui/large_stack_frames.stderr new file mode 100644 index 000000000000..d57df8596fe5 --- /dev/null +++ b/tests/ui/large_stack_frames.stderr @@ -0,0 +1,37 @@ +error: this function allocates a large amount of stack space + --> $DIR/large_stack_frames.rs:25:1 + | +LL | / fn many_small_arrays() { +LL | | let x = [0u8; 500_000]; +LL | | let x2 = [0u8; 500_000]; +LL | | let x3 = [0u8; 500_000]; +... | +LL | | black_box((&x, &x2, &x3, &x4, &x5)); +LL | | } + | |_^ + | + = note: allocating large amounts of stack space can overflow the stack + = note: `-D clippy::large-stack-frames` implied by `-D warnings` + +error: this function allocates a large amount of stack space + --> $DIR/large_stack_frames.rs:34:1 + | +LL | / fn large_return_value() -> ArrayDefault<1_000_000> { +LL | | Default::default() +LL | | } + | |_^ + | + = note: allocating large amounts of stack space can overflow the stack + +error: this function allocates a large amount of stack space + --> $DIR/large_stack_frames.rs:38:1 + | +LL | / fn large_fn_arg(x: ArrayDefault<1_000_000>) { +LL | | black_box(&x); +LL | | } + | |_^ + | + = note: allocating large amounts of stack space can overflow the stack + +error: aborting due to 3 previous errors + diff --git a/tests/ui/large_types_passed_by_value.rs b/tests/ui/large_types_passed_by_value.rs index 7601b5c66fa3..f9e3c7192ad5 100644 --- a/tests/ui/large_types_passed_by_value.rs +++ b/tests/ui/large_types_passed_by_value.rs @@ -1,5 +1,5 @@ -// normalize-stderr-test "\(\d+ byte\)" -> "(N byte)" -// normalize-stderr-test "\(limit: \d+ byte\)" -> "(limit: N byte)" +//@normalize-stderr-test: "\(\d+ byte\)" -> "(N byte)" +//@normalize-stderr-test: "\(limit: \d+ byte\)" -> "(limit: N byte)" #![warn(clippy::large_types_passed_by_value)] diff --git a/tests/ui/len_zero.fixed b/tests/ui/len_zero.fixed index c1c0b5ae40f6..fafee6a0d41d 100644 --- a/tests/ui/len_zero.fixed +++ b/tests/ui/len_zero.fixed @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::len_zero)] -#![allow(dead_code, unused, clippy::len_without_is_empty)] +#![allow(dead_code, unused, clippy::needless_if, clippy::len_without_is_empty)] extern crate core; use core::ops::Deref; @@ -176,6 +176,10 @@ fn main() { // No error; `HasWrongIsEmpty` does not have `.is_empty()`. println!("Or this!"); } + + // issue #10529 + (!has_is_empty.is_empty()).then(|| println!("This can happen.")); + (has_is_empty.is_empty()).then(|| println!("Or this!")); } fn test_slice(b: &[u8]) { diff --git a/tests/ui/len_zero.rs b/tests/ui/len_zero.rs index cc2eb05b6bfd..6a9006c47799 100644 --- a/tests/ui/len_zero.rs +++ b/tests/ui/len_zero.rs @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::len_zero)] -#![allow(dead_code, unused, clippy::len_without_is_empty)] +#![allow(dead_code, unused, clippy::needless_if, clippy::len_without_is_empty)] extern crate core; use core::ops::Deref; @@ -176,6 +176,10 @@ fn main() { // No error; `HasWrongIsEmpty` does not have `.is_empty()`. println!("Or this!"); } + + // issue #10529 + (has_is_empty.len() > 0).then(|| println!("This can happen.")); + (has_is_empty.len() == 0).then(|| println!("Or this!")); } fn test_slice(b: &[u8]) { diff --git a/tests/ui/len_zero.stderr b/tests/ui/len_zero.stderr index b6f13780253c..396cfb75fb62 100644 --- a/tests/ui/len_zero.stderr +++ b/tests/ui/len_zero.stderr @@ -123,10 +123,22 @@ LL | if with_is_empty.len() == 0 { | ^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `with_is_empty.is_empty()` error: length comparison to zero - --> $DIR/len_zero.rs:182:8 + --> $DIR/len_zero.rs:181:6 + | +LL | (has_is_empty.len() > 0).then(|| println!("This can happen.")); + | ^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` + +error: length comparison to zero + --> $DIR/len_zero.rs:182:6 + | +LL | (has_is_empty.len() == 0).then(|| println!("Or this!")); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` + +error: length comparison to zero + --> $DIR/len_zero.rs:186:8 | LL | if b.len() != 0 {} | ^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!b.is_empty()` -error: aborting due to 21 previous errors +error: aborting due to 23 previous errors diff --git a/tests/ui/len_zero_ranges.fixed b/tests/ui/len_zero_ranges.fixed index 797817662427..4b1241ec86b4 100644 --- a/tests/ui/len_zero_ranges.fixed +++ b/tests/ui/len_zero_ranges.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::len_zero)] #![allow(unused)] diff --git a/tests/ui/len_zero_ranges.rs b/tests/ui/len_zero_ranges.rs index a0eb51cc9760..4b47132c7661 100644 --- a/tests/ui/len_zero_ranges.rs +++ b/tests/ui/len_zero_ranges.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::len_zero)] #![allow(unused)] diff --git a/tests/ui/let_and_return.rs b/tests/ui/let_and_return.rs index bb162adc9adb..7e4d783a026c 100644 --- a/tests/ui/let_and_return.rs +++ b/tests/ui/let_and_return.rs @@ -1,6 +1,8 @@ #![allow(unused)] #![warn(clippy::let_and_return)] +use std::cell::RefCell; + fn test() -> i32 { let _y = 0; // no warning let x = 5; @@ -65,45 +67,46 @@ macro_rules! tuple_encode { ); } +fn issue_3792() -> String { + use std::io::{self, BufRead, Stdin}; + + let stdin = io::stdin(); + // `Stdin::lock` returns `StdinLock<'static>` so `line` doesn't borrow from `stdin` + // https://github.com/rust-lang/rust/pull/93965 + let line = stdin.lock().lines().next().unwrap().unwrap(); + line +} + tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7); mod no_lint_if_stmt_borrows { - mod issue_3792 { - use std::io::{self, BufRead, Stdin}; + use std::cell::RefCell; + use std::rc::{Rc, Weak}; + struct Bar; - fn read_line() -> String { - let stdin = io::stdin(); - let line = stdin.lock().lines().next().unwrap().unwrap(); - line + impl Bar { + fn new() -> Self { + Bar {} } - } - - mod issue_3324 { - use std::cell::RefCell; - use std::rc::{Rc, Weak}; - - fn test(value: Weak>) -> u32 { - let value = value.upgrade().unwrap(); - let ret = value.borrow().baz(); - ret + fn baz(&self) -> u32 { + 0 } + } - struct Bar; + fn issue_3324(value: Weak>) -> u32 { + let value = value.upgrade().unwrap(); + let ret = value.borrow().baz(); + ret + } - impl Bar { - fn new() -> Self { - Bar {} - } - fn baz(&self) -> u32 { - 0 - } + fn borrows_in_closure(value: Weak>) -> u32 { + fn f(mut x: impl FnMut() -> u32) -> impl FnMut() -> u32 { + x } - fn main() { - let a = Rc::new(RefCell::new(Bar::new())); - let b = Rc::downgrade(&a); - test(b); - } + let value = value.upgrade().unwrap(); + let ret = f(|| value.borrow().baz())(); + ret } mod free_function { diff --git a/tests/ui/let_and_return.stderr b/tests/ui/let_and_return.stderr index 17fd694bf7ac..4ca0a05c858f 100644 --- a/tests/ui/let_and_return.stderr +++ b/tests/ui/let_and_return.stderr @@ -1,5 +1,5 @@ error: returning the result of a `let` binding from a block - --> $DIR/let_and_return.rs:7:5 + --> $DIR/let_and_return.rs:9:5 | LL | let x = 5; | ---------- unnecessary `let` binding @@ -14,7 +14,7 @@ LL ~ 5 | error: returning the result of a `let` binding from a block - --> $DIR/let_and_return.rs:13:9 + --> $DIR/let_and_return.rs:15:9 | LL | let x = 5; | ---------- unnecessary `let` binding @@ -28,7 +28,21 @@ LL ~ 5 | error: returning the result of a `let` binding from a block - --> $DIR/let_and_return.rs:164:13 + --> $DIR/let_and_return.rs:77:5 + | +LL | let line = stdin.lock().lines().next().unwrap().unwrap(); + | --------------------------------------------------------- unnecessary `let` binding +LL | line + | ^^^^ + | +help: return the expression directly + | +LL ~ +LL ~ stdin.lock().lines().next().unwrap().unwrap() + | + +error: returning the result of a `let` binding from a block + --> $DIR/let_and_return.rs:167:13 | LL | let clone = Arc::clone(&self.foo); | ---------------------------------- unnecessary `let` binding @@ -41,5 +55,5 @@ LL ~ LL ~ Arc::clone(&self.foo) as _ | -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/let_underscore_future.stderr b/tests/ui/let_underscore_future.stderr index 33a748736a88..9e69fb041330 100644 --- a/tests/ui/let_underscore_future.stderr +++ b/tests/ui/let_underscore_future.stderr @@ -1,3 +1,11 @@ +error: this argument is a mutable reference, but not used mutably + --> $DIR/let_underscore_future.rs:11:35 + | +LL | fn do_something_to_future(future: &mut impl Future) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&impl Future` + | + = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` + error: non-binding `let` on a future --> $DIR/let_underscore_future.rs:14:5 | @@ -23,5 +31,5 @@ LL | let _ = future; | = help: consider awaiting the future or dropping explicitly with `std::mem::drop` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/let_underscore_lock.rs b/tests/ui/let_underscore_lock.rs index 4dff4d766bcc..87f12e2789f0 100644 --- a/tests/ui/let_underscore_lock.rs +++ b/tests/ui/let_underscore_lock.rs @@ -3,7 +3,8 @@ extern crate parking_lot; fn main() { - use parking_lot::{lock_api::RawMutex, Mutex, RwLock}; + use parking_lot::lock_api::RawMutex; + use parking_lot::{Mutex, RwLock}; let p_m: Mutex<()> = Mutex::const_new(RawMutex::INIT, ()); let _ = p_m.lock(); diff --git a/tests/ui/let_underscore_lock.stderr b/tests/ui/let_underscore_lock.stderr index f137d4112092..5027e6b3cbc7 100644 --- a/tests/ui/let_underscore_lock.stderr +++ b/tests/ui/let_underscore_lock.stderr @@ -1,5 +1,5 @@ error: non-binding `let` on a synchronization lock - --> $DIR/let_underscore_lock.rs:9:5 + --> $DIR/let_underscore_lock.rs:10:5 | LL | let _ = p_m.lock(); | ^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let _ = p_m.lock(); = note: `-D clippy::let-underscore-lock` implied by `-D warnings` error: non-binding `let` on a synchronization lock - --> $DIR/let_underscore_lock.rs:12:5 + --> $DIR/let_underscore_lock.rs:13:5 | LL | let _ = p_m1.lock(); | ^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | let _ = p_m1.lock(); = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop` error: non-binding `let` on a synchronization lock - --> $DIR/let_underscore_lock.rs:15:5 + --> $DIR/let_underscore_lock.rs:16:5 | LL | let _ = p_rw.read(); | ^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | let _ = p_rw.read(); = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop` error: non-binding `let` on a synchronization lock - --> $DIR/let_underscore_lock.rs:16:5 + --> $DIR/let_underscore_lock.rs:17:5 | LL | let _ = p_rw.write(); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/let_underscore_untyped.rs b/tests/ui/let_underscore_untyped.rs index bcb33c5c7e37..c248d2811b99 100644 --- a/tests/ui/let_underscore_untyped.rs +++ b/tests/ui/let_underscore_untyped.rs @@ -1,8 +1,23 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e234dfa63 (Ignoring `let_underscore_untyped` warnings in code from proc macros) +======= +//@aux-build: proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) + #![allow(unused)] #![warn(clippy::let_underscore_untyped)] +extern crate proc_macros; +use proc_macros::with_span; + +use clippy_utils::is_from_proc_macro; +use std::boxed::Box; +use std::fmt::Display; use std::future::Future; -use std::{boxed::Box, fmt::Display}; fn a() -> u32 { 1 @@ -28,6 +43,21 @@ fn f() -> Box { Box::new(1) } +fn g() -> impl Fn() { + || {} +} + +<<<<<<< HEAD +with_span!( + span + + fn dont_lint_proc_macro() { + let _ = a(); + } +); + +======= +>>>>>>> e4f5d83fa (Fixed formatting.) fn main() { let _ = a(); let _ = b(1); @@ -35,6 +65,11 @@ fn main() { let _ = d(&1); let _ = e(); let _ = f(); + let _ = g(); +<<<<<<< HEAD + let closure = || {}; +======= +>>>>>>> e4f5d83fa (Fixed formatting.) _ = a(); _ = b(1); diff --git a/tests/ui/let_underscore_untyped.stderr b/tests/ui/let_underscore_untyped.stderr index 36c3d1214d6b..42404b3f9d49 100644 --- a/tests/ui/let_underscore_untyped.stderr +++ b/tests/ui/let_underscore_untyped.stderr @@ -1,51 +1,173 @@ error: non-binding `let` without a type annotation - --> $DIR/let_underscore_untyped.rs:32:5 +<<<<<<< HEAD + --> $DIR/let_underscore_untyped.rs:51:5 +======= + --> $DIR/let_underscore_untyped.rs:36:5 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | let _ = a(); | ^^^^^^^^^^^^ | - = help: consider adding a type annotation or removing the `let` keyword +help: consider adding a type annotation +<<<<<<< HEAD + --> $DIR/let_underscore_untyped.rs:51:10 +======= + --> $DIR/let_underscore_untyped.rs:36:10 +>>>>>>> e4f5d83fa (Fixed formatting.) + | +LL | let _ = a(); + | ^ = note: `-D clippy::let-underscore-untyped` implied by `-D warnings` error: non-binding `let` without a type annotation - --> $DIR/let_underscore_untyped.rs:33:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/let_underscore_untyped.rs:37:5 +<<<<<<< HEAD +<<<<<<< HEAD +======= +======= +>>>>>>> bdd05456b (Ignore `impl Trait`(s)) +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/let_underscore_untyped.rs:52:5 +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) | LL | let _ = b(1); | ^^^^^^^^^^^^^ | - = help: consider adding a type annotation or removing the `let` keyword +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:52:10 + | +LL | let _ = b(1); + | ^ + +error: non-binding `let` without a type annotation + --> $DIR/let_underscore_untyped.rs:54:5 + | +LL | let _ = d(&1); + | ^^^^^^^^^^^^^^ + | +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:54:10 + | +LL | let _ = d(&1); + | ^ error: non-binding `let` without a type annotation - --> $DIR/let_underscore_untyped.rs:34:5 + --> $DIR/let_underscore_untyped.rs:55:5 | -LL | let _ = c(); +LL | let _ = e(); | ^^^^^^^^^^^^ | - = help: consider adding a type annotation or removing the `let` keyword +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:55:10 + | +LL | let _ = e(); + | ^ + +error: non-binding `let` without a type annotation +<<<<<<< HEAD + --> $DIR/let_underscore_untyped.rs:41:5 +<<<<<<< HEAD +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) + | +LL | let _ = b(1); + | ^^^^^^^^^^^^^ + | +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:37:10 + | +LL | let _ = b(1); + | ^ error: non-binding `let` without a type annotation - --> $DIR/let_underscore_untyped.rs:35:5 + --> $DIR/let_underscore_untyped.rs:39:5 | LL | let _ = d(&1); | ^^^^^^^^^^^^^^ | - = help: consider adding a type annotation or removing the `let` keyword +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:39:10 + | +LL | let _ = d(&1); + | ^ error: non-binding `let` without a type annotation - --> $DIR/let_underscore_untyped.rs:36:5 + --> $DIR/let_underscore_untyped.rs:40:5 | LL | let _ = e(); | ^^^^^^^^^^^^ | - = help: consider adding a type annotation or removing the `let` keyword +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:40:10 + | +LL | let _ = e(); + | ^ error: non-binding `let` without a type annotation + --> $DIR/let_underscore_untyped.rs:41:5 +======= +>>>>>>> bdd05456b (Ignore `impl Trait`(s)) +======= + --> $DIR/let_underscore_untyped.rs:56:5 +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= --> $DIR/let_underscore_untyped.rs:37:5 +>>>>>>> e4f5d83fa (Fixed formatting.) + | +LL | let _ = b(1); + | ^^^^^^^^^^^^^ + | +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:37:10 + | +LL | let _ = b(1); + | ^ + +error: non-binding `let` without a type annotation + --> $DIR/let_underscore_untyped.rs:39:5 + | +LL | let _ = d(&1); + | ^^^^^^^^^^^^^^ + | +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:39:10 + | +LL | let _ = d(&1); + | ^ + +error: non-binding `let` without a type annotation + --> $DIR/let_underscore_untyped.rs:40:5 + | +LL | let _ = e(); + | ^^^^^^^^^^^^ + | +help: consider adding a type annotation + --> $DIR/let_underscore_untyped.rs:40:10 + | +LL | let _ = e(); + | ^ + +error: non-binding `let` without a type annotation + --> $DIR/let_underscore_untyped.rs:41:5 +>>>>>>> 4da6e7e06 (rebase attempt) | LL | let _ = f(); | ^^^^^^^^^^^^ | - = help: consider adding a type annotation or removing the `let` keyword +help: consider adding a type annotation +<<<<<<< HEAD + --> $DIR/let_underscore_untyped.rs:56:10 +======= + --> $DIR/let_underscore_untyped.rs:41:10 +>>>>>>> e4f5d83fa (Fixed formatting.) + | +LL | let _ = f(); + | ^ -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors diff --git a/tests/ui/let_unit.fixed b/tests/ui/let_unit.fixed index 76ff0645f417..8ba89ec78bbd 100644 --- a/tests/ui/let_unit.fixed +++ b/tests/ui/let_unit.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![warn(clippy::let_unit_value)] diff --git a/tests/ui/let_unit.rs b/tests/ui/let_unit.rs index 895ccfe366a2..7e8764a482a2 100644 --- a/tests/ui/let_unit.rs +++ b/tests/ui/let_unit.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![warn(clippy::let_unit_value)] diff --git a/tests/ui/let_with_type_underscore.rs b/tests/ui/let_with_type_underscore.rs index 175718b94c8e..d32501d11b46 100644 --- a/tests/ui/let_with_type_underscore.rs +++ b/tests/ui/let_with_type_underscore.rs @@ -1,19 +1,80 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> 0cc1454db (Fix #10498) +======= +//@aux-build: proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) #![allow(unused)] #![warn(clippy::let_with_type_underscore)] -#![allow(clippy::let_unit_value)] +#![allow(clippy::let_unit_value, clippy::needless_late_init)] +<<<<<<< HEAD + +extern crate proc_macros; +======= +>>>>>>> 143ff2dfc (Use type snippet instead of init expr for proc macro check) + +extern crate proc_macros; fn func() -> &'static str { "" } +#[rustfmt::skip] fn main() { // Will lint let x: _ = 1; let _: _ = 2; let x: _ = func(); + let x: _; + x = (); - let x = 1; // Will not lint, Rust inferres this to an integer before Clippy + let x = 1; // Will not lint, Rust infers this to an integer before Clippy let x = func(); let x: Vec<_> = Vec::::new(); let x: [_; 1] = [1]; +<<<<<<< HEAD +<<<<<<< HEAD + let x : _ = 1; + + // Do not lint from procedural macros + proc_macros::with_span! { + span + let x: _ = (); + // Late initialization + let x: _; + x = (); + // Ensure weird formatting will not break it (hopefully) + let x : _ = 1; + let x +: _ = 1; + let x : + _; + x = (); +======= +======= + let x : _ = 1; +>>>>>>> 143ff2dfc (Use type snippet instead of init expr for proc macro check) + + // Do not lint from procedural macros + proc_macros::with_span! { + span + let x: _ = (); +<<<<<<< HEAD +>>>>>>> 0cc1454db (Fix #10498) +======= + // Late initialization + let x: _; + x = (); + // Ensure weird formatting will not break it (hopefully) + let x : _ = 1; + let x +: _ = 1; + let x : + _; + x = (); +>>>>>>> 143ff2dfc (Use type snippet instead of init expr for proc macro check) + }; } diff --git a/tests/ui/let_with_type_underscore.stderr b/tests/ui/let_with_type_underscore.stderr index 16bf83c708fe..a4c440364962 100644 --- a/tests/ui/let_with_type_underscore.stderr +++ b/tests/ui/let_with_type_underscore.stderr @@ -1,39 +1,111 @@ error: variable declared with type underscore - --> $DIR/let_with_type_underscore.rs:11:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/let_with_type_underscore.rs:15:5 +======= + --> $DIR/let_with_type_underscore.rs:14:5 +>>>>>>> 0cc1454db (Fix #10498) +======= + --> $DIR/let_with_type_underscore.rs:15:5 +>>>>>>> 143ff2dfc (Use type snippet instead of init expr for proc macro check) | LL | let x: _ = 1; | ^^^^^^^^^^^^^ | help: remove the explicit type `_` declaration - --> $DIR/let_with_type_underscore.rs:11:10 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/let_with_type_underscore.rs:15:10 +======= + --> $DIR/let_with_type_underscore.rs:14:10 +>>>>>>> 0cc1454db (Fix #10498) +======= + --> $DIR/let_with_type_underscore.rs:15:10 +>>>>>>> 143ff2dfc (Use type snippet instead of init expr for proc macro check) | LL | let x: _ = 1; | ^^^ = note: `-D clippy::let-with-type-underscore` implied by `-D warnings` error: variable declared with type underscore - --> $DIR/let_with_type_underscore.rs:12:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/let_with_type_underscore.rs:16:5 +======= + --> $DIR/let_with_type_underscore.rs:15:5 +>>>>>>> 0cc1454db (Fix #10498) +======= + --> $DIR/let_with_type_underscore.rs:16:5 +>>>>>>> 143ff2dfc (Use type snippet instead of init expr for proc macro check) | LL | let _: _ = 2; | ^^^^^^^^^^^^^ | help: remove the explicit type `_` declaration - --> $DIR/let_with_type_underscore.rs:12:10 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/let_with_type_underscore.rs:16:10 +======= + --> $DIR/let_with_type_underscore.rs:15:10 +>>>>>>> 0cc1454db (Fix #10498) +======= + --> $DIR/let_with_type_underscore.rs:16:10 +>>>>>>> 143ff2dfc (Use type snippet instead of init expr for proc macro check) | LL | let _: _ = 2; | ^^^ error: variable declared with type underscore - --> $DIR/let_with_type_underscore.rs:13:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/let_with_type_underscore.rs:17:5 +======= + --> $DIR/let_with_type_underscore.rs:16:5 +>>>>>>> 0cc1454db (Fix #10498) +======= + --> $DIR/let_with_type_underscore.rs:17:5 +>>>>>>> 143ff2dfc (Use type snippet instead of init expr for proc macro check) | LL | let x: _ = func(); | ^^^^^^^^^^^^^^^^^^ | help: remove the explicit type `_` declaration - --> $DIR/let_with_type_underscore.rs:13:10 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/let_with_type_underscore.rs:17:10 +======= + --> $DIR/let_with_type_underscore.rs:16:10 +>>>>>>> 0cc1454db (Fix #10498) +======= + --> $DIR/let_with_type_underscore.rs:17:10 +>>>>>>> 143ff2dfc (Use type snippet instead of init expr for proc macro check) | LL | let x: _ = func(); | ^^^ -error: aborting due to 3 previous errors +error: variable declared with type underscore + --> $DIR/let_with_type_underscore.rs:18:5 + | +LL | let x: _; + | ^^^^^^^^^ + | +help: remove the explicit type `_` declaration + --> $DIR/let_with_type_underscore.rs:18:10 + | +LL | let x: _; + | ^^^ + +error: variable declared with type underscore + --> $DIR/let_with_type_underscore.rs:25:5 + | +LL | let x : _ = 1; + | ^^^^^^^^^^^^^^ + | +help: remove the explicit type `_` declaration + --> $DIR/let_with_type_underscore.rs:25:10 + | +LL | let x : _ = 1; + | ^^^^ + +error: aborting due to 5 previous errors diff --git a/tests/ui/lines_filter_map_ok.fixed b/tests/ui/lines_filter_map_ok.fixed index f4033cd8ed85..5ff938c80e25 100644 --- a/tests/ui/lines_filter_map_ok.fixed +++ b/tests/ui/lines_filter_map_ok.fixed @@ -1,4 +1,16 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= // run-rustfix +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +//@run-rustfix +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +//@run-rustfix +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) #![allow(unused, clippy::map_identity)] #![warn(clippy::lines_filter_map_ok)] diff --git a/tests/ui/lines_filter_map_ok.rs b/tests/ui/lines_filter_map_ok.rs index 7e11816b2acd..d54605261563 100644 --- a/tests/ui/lines_filter_map_ok.rs +++ b/tests/ui/lines_filter_map_ok.rs @@ -1,4 +1,16 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= // run-rustfix +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +//@run-rustfix +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +//@run-rustfix +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) #![allow(unused, clippy::map_identity)] #![warn(clippy::lines_filter_map_ok)] diff --git a/tests/ui/lossy_float_literal.fixed b/tests/ui/lossy_float_literal.fixed index 24e372354fc0..e19f4980cd70 100644 --- a/tests/ui/lossy_float_literal.fixed +++ b/tests/ui/lossy_float_literal.fixed @@ -1,5 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::lossy_float_literal)] +#![allow(overflowing_literals, unused)] fn main() { // Lossy whole-number float literals @@ -32,4 +33,7 @@ fn main() { let _: f64 = 1e99; let _: f64 = 1E99; let _: f32 = 0.1; + + const INF1: f32 = 1000000000000000000000000000000000f32; + const NEG_INF1: f32 = -340282357000000000000000000000000000001_f32; } diff --git a/tests/ui/lossy_float_literal.rs b/tests/ui/lossy_float_literal.rs index 3dcf98fa0bdd..a2a1cfb317e1 100644 --- a/tests/ui/lossy_float_literal.rs +++ b/tests/ui/lossy_float_literal.rs @@ -1,5 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::lossy_float_literal)] +#![allow(overflowing_literals, unused)] fn main() { // Lossy whole-number float literals @@ -32,4 +33,7 @@ fn main() { let _: f64 = 1e99; let _: f64 = 1E99; let _: f32 = 0.1; + + const INF1: f32 = 1000000000000000000000000000000000f32; + const NEG_INF1: f32 = -340282357000000000000000000000000000001_f32; } diff --git a/tests/ui/lossy_float_literal.stderr b/tests/ui/lossy_float_literal.stderr index d2193c0c8195..2d72b16430c4 100644 --- a/tests/ui/lossy_float_literal.stderr +++ b/tests/ui/lossy_float_literal.stderr @@ -1,5 +1,5 @@ error: literal cannot be represented as the underlying type without loss of precision - --> $DIR/lossy_float_literal.rs:6:18 + --> $DIR/lossy_float_literal.rs:7:18 | LL | let _: f32 = 16_777_217.0; | ^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_216.0` @@ -7,61 +7,61 @@ LL | let _: f32 = 16_777_217.0; = note: `-D clippy::lossy-float-literal` implied by `-D warnings` error: literal cannot be represented as the underlying type without loss of precision - --> $DIR/lossy_float_literal.rs:7:18 + --> $DIR/lossy_float_literal.rs:8:18 | LL | let _: f32 = 16_777_219.0; | ^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0` error: literal cannot be represented as the underlying type without loss of precision - --> $DIR/lossy_float_literal.rs:8:18 + --> $DIR/lossy_float_literal.rs:9:18 | LL | let _: f32 = 16_777_219.; | ^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0` error: literal cannot be represented as the underlying type without loss of precision - --> $DIR/lossy_float_literal.rs:9:18 + --> $DIR/lossy_float_literal.rs:10:18 | LL | let _: f32 = 16_777_219.000; | ^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0` error: literal cannot be represented as the underlying type without loss of precision - --> $DIR/lossy_float_literal.rs:10:13 + --> $DIR/lossy_float_literal.rs:11:13 | LL | let _ = 16_777_219f32; | ^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220_f32` error: literal cannot be represented as the underlying type without loss of precision - --> $DIR/lossy_float_literal.rs:11:19 + --> $DIR/lossy_float_literal.rs:12:19 | LL | let _: f32 = -16_777_219.0; | ^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0` error: literal cannot be represented as the underlying type without loss of precision - --> $DIR/lossy_float_literal.rs:12:18 + --> $DIR/lossy_float_literal.rs:13:18 | LL | let _: f64 = 9_007_199_254_740_993.0; | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0` error: literal cannot be represented as the underlying type without loss of precision - --> $DIR/lossy_float_literal.rs:13:18 + --> $DIR/lossy_float_literal.rs:14:18 | LL | let _: f64 = 9_007_199_254_740_993.; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0` error: literal cannot be represented as the underlying type without loss of precision - --> $DIR/lossy_float_literal.rs:14:18 + --> $DIR/lossy_float_literal.rs:15:18 | LL | let _: f64 = 9_007_199_254_740_993.00; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0` error: literal cannot be represented as the underlying type without loss of precision - --> $DIR/lossy_float_literal.rs:15:13 + --> $DIR/lossy_float_literal.rs:16:13 | LL | let _ = 9_007_199_254_740_993f64; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992_f64` error: literal cannot be represented as the underlying type without loss of precision - --> $DIR/lossy_float_literal.rs:16:19 + --> $DIR/lossy_float_literal.rs:17:19 | LL | let _: f64 = -9_007_199_254_740_993.0; | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0` diff --git a/tests/ui/macro_use_imports.fixed b/tests/ui/macro_use_imports.fixed index 15f7a099a7de..1de021e0687f 100644 --- a/tests/ui/macro_use_imports.fixed +++ b/tests/ui/macro_use_imports.fixed @@ -1,8 +1,12 @@ -// aux-build:macro_rules.rs -// aux-build:macro_use_helper.rs -// aux-build:proc_macro_derive.rs -// run-rustfix -// ignore-32bit +//@aux-build:macro_rules.rs +//@aux-build:macro_use_helper.rs +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) +//@run-rustfix +//@ignore-32bit #![feature(lint_reasons)] #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)] @@ -16,7 +20,7 @@ extern crate macro_use_helper as mac; extern crate proc_macro_derive as mini_mac; mod a { - use mac::{pub_macro, function_macro, ty_macro, inner_mod_macro, pub_in_private_macro}; + use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro}; use mac; use mini_mac::ClippyMiniMacroTest; use mini_mac; diff --git a/tests/ui/macro_use_imports.rs b/tests/ui/macro_use_imports.rs index b1a287332949..0402c0617638 100644 --- a/tests/ui/macro_use_imports.rs +++ b/tests/ui/macro_use_imports.rs @@ -1,8 +1,12 @@ -// aux-build:macro_rules.rs -// aux-build:macro_use_helper.rs -// aux-build:proc_macro_derive.rs -// run-rustfix -// ignore-32bit +//@aux-build:macro_rules.rs +//@aux-build:macro_use_helper.rs +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) +//@run-rustfix +//@ignore-32bit #![feature(lint_reasons)] #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)] diff --git a/tests/ui/macro_use_imports.stderr b/tests/ui/macro_use_imports.stderr index 68d558dede05..4abbbef2ca6f 100644 --- a/tests/ui/macro_use_imports.stderr +++ b/tests/ui/macro_use_imports.stderr @@ -1,28 +1,32 @@ error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> $DIR/macro_use_imports.rs:25:5 + --> $DIR/macro_use_imports.rs:19:5 | LL | #[macro_use] - | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;` + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};` | = note: `-D clippy::macro-use-imports` implied by `-D warnings` error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> $DIR/macro_use_imports.rs:21:5 + --> $DIR/macro_use_imports.rs:23:5 | LL | #[macro_use] - | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;` + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};` error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> $DIR/macro_use_imports.rs:23:5 + --> $DIR/macro_use_imports.rs:25:5 | LL | #[macro_use] - | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};` +<<<<<<< HEAD + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;` error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> $DIR/macro_use_imports.rs:19:5 + --> $DIR/macro_use_imports.rs:21:5 | LL | #[macro_use] - | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, function_macro, ty_macro, inner_mod_macro, pub_in_private_macro};` + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;` +======= + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};` +>>>>>>> e4f5d83fa (Fixed formatting.) error: aborting due to 4 previous errors diff --git a/tests/ui/macro_use_imports_expect.rs b/tests/ui/macro_use_imports_expect.rs index 5aac5af26db5..e09fc5f99939 100644 --- a/tests/ui/macro_use_imports_expect.rs +++ b/tests/ui/macro_use_imports_expect.rs @@ -1,7 +1,11 @@ -// aux-build:macro_rules.rs -// aux-build:macro_use_helper.rs -// aux-build:proc_macro_derive.rs -// ignore-32bit +//@aux-build:macro_rules.rs +//@aux-build:macro_use_helper.rs +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) +//@ignore-32bit #![feature(lint_reasons)] #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)] diff --git a/tests/ui/manual_assert.edition2018.fixed b/tests/ui/manual_assert.edition2018.fixed index 8c7e919bf62a..d8dde0236eae 100644 --- a/tests/ui/manual_assert.edition2018.fixed +++ b/tests/ui/manual_assert.edition2018.fixed @@ -1,11 +1,11 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::manual_assert)] #![allow(dead_code, unused_doc_comments)] -#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args)] +#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)] macro_rules! one { () => { diff --git a/tests/ui/manual_assert.edition2021.fixed b/tests/ui/manual_assert.edition2021.fixed index 8c7e919bf62a..d8dde0236eae 100644 --- a/tests/ui/manual_assert.edition2021.fixed +++ b/tests/ui/manual_assert.edition2021.fixed @@ -1,11 +1,11 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::manual_assert)] #![allow(dead_code, unused_doc_comments)] -#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args)] +#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)] macro_rules! one { () => { diff --git a/tests/ui/manual_assert.rs b/tests/ui/manual_assert.rs index f037c5b8405c..0f87d6e2d2c9 100644 --- a/tests/ui/manual_assert.rs +++ b/tests/ui/manual_assert.rs @@ -1,11 +1,11 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::manual_assert)] #![allow(dead_code, unused_doc_comments)] -#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args)] +#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)] macro_rules! one { () => { diff --git a/tests/ui/manual_async_fn.fixed b/tests/ui/manual_async_fn.fixed index 5cc4a43af7e3..e609b4b1bdb0 100644 --- a/tests/ui/manual_async_fn.fixed +++ b/tests/ui/manual_async_fn.fixed @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_async_fn)] -#![allow(unused)] +#![allow(clippy::needless_pub_self, unused)] use std::future::Future; diff --git a/tests/ui/manual_async_fn.rs b/tests/ui/manual_async_fn.rs index ba504b8a8231..6c1a9edaa110 100644 --- a/tests/ui/manual_async_fn.rs +++ b/tests/ui/manual_async_fn.rs @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_async_fn)] -#![allow(unused)] +#![allow(clippy::needless_pub_self, unused)] use std::future::Future; diff --git a/tests/ui/manual_bits.fixed b/tests/ui/manual_bits.fixed index e7f8cd878ca7..037de0262e2f 100644 --- a/tests/ui/manual_bits.fixed +++ b/tests/ui/manual_bits.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_bits)] #![allow( diff --git a/tests/ui/manual_bits.rs b/tests/ui/manual_bits.rs index 7b1d15495287..b15a531ec175 100644 --- a/tests/ui/manual_bits.rs +++ b/tests/ui/manual_bits.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_bits)] #![allow( diff --git a/tests/ui/manual_filter.fixed b/tests/ui/manual_filter.fixed index ef6780dc96d9..5e3b12e510b8 100644 --- a/tests/ui/manual_filter.fixed +++ b/tests/ui/manual_filter.fixed @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_filter)] -#![allow(unused_variables, dead_code)] +#![allow(unused_variables, dead_code, clippy::useless_vec)] fn main() { Some(0).filter(|&x| x <= 0); diff --git a/tests/ui/manual_filter.rs b/tests/ui/manual_filter.rs index ea0ce83172b7..b81604b0372b 100644 --- a/tests/ui/manual_filter.rs +++ b/tests/ui/manual_filter.rs @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_filter)] -#![allow(unused_variables, dead_code)] +#![allow(unused_variables, dead_code, clippy::useless_vec)] fn main() { match Some(0) { diff --git a/tests/ui/manual_filter.stderr b/tests/ui/manual_filter.stderr index 53dea9229306..f62d3e960594 100644 --- a/tests/ui/manual_filter.stderr +++ b/tests/ui/manual_filter.stderr @@ -8,7 +8,7 @@ LL | | if x > 0 { ... | LL | | }, LL | | }; - | |_____^ help: try this: `Some(0).filter(|&x| x <= 0)` + | |_____^ help: try: `Some(0).filter(|&x| x <= 0)` | = note: `-D clippy::manual-filter` implied by `-D warnings` @@ -22,7 +22,7 @@ LL | | None ... | LL | | None => None, LL | | }; - | |_____^ help: try this: `Some(1).filter(|&x| x <= 0)` + | |_____^ help: try: `Some(1).filter(|&x| x <= 0)` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:29:5 @@ -34,7 +34,7 @@ LL | | None ... | LL | | _ => None, LL | | }; - | |_____^ help: try this: `Some(2).filter(|&x| x <= 0)` + | |_____^ help: try: `Some(2).filter(|&x| x <= 0)` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:40:5 @@ -46,7 +46,7 @@ LL | | Some(x) ... | LL | | None => None, LL | | }; - | |_____^ help: try this: `Some(3).filter(|&x| x > 0)` + | |_____^ help: try: `Some(3).filter(|&x| x > 0)` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:52:5 @@ -58,7 +58,7 @@ LL | | Some(x) => { ... | LL | | }, LL | | }; - | |_____^ help: try this: `y.filter(|&x| x <= 0)` + | |_____^ help: try: `y.filter(|&x| x <= 0)` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:64:5 @@ -70,7 +70,7 @@ LL | | Some(x) ... | LL | | _ => None, LL | | }; - | |_____^ help: try this: `Some(5).filter(|&x| x > 0)` + | |_____^ help: try: `Some(5).filter(|&x| x > 0)` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:75:5 @@ -82,7 +82,7 @@ LL | | Some(x) ... | LL | | _ => None, LL | | }; - | |_____^ help: try this: `Some(6).as_ref().filter(|&x| x > &0)` + | |_____^ help: try: `Some(6).as_ref().filter(|&x| x > &0)` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:87:5 @@ -94,7 +94,7 @@ LL | | Some(x) ... | LL | | _ => None, LL | | }; - | |_____^ help: try this: `Some(String::new()).filter(|x| external_cond)` + | |_____^ help: try: `Some(String::new()).filter(|x| external_cond)` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:98:5 @@ -104,7 +104,7 @@ LL | | if external_cond { Some(x) } else { None } LL | | } else { LL | | None LL | | }; - | |_____^ help: try this: `Some(7).filter(|&x| external_cond)` + | |_____^ help: try: `Some(7).filter(|&x| external_cond)` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:104:5 @@ -116,7 +116,7 @@ LL | | Some(x) ... | LL | | _ => None, LL | | }; - | |_____^ help: try this: `Some(8).filter(|&x| x != 0)` + | |_____^ help: try: `Some(8).filter(|&x| x != 0)` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:115:5 @@ -128,7 +128,7 @@ LL | | Some(x) ... | LL | | None => None, LL | | }; - | |_____^ help: try this: `Some(9).filter(|&x| x > 10 && x < 100)` + | |_____^ help: try: `Some(9).filter(|&x| x > 10 && x < 100)` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:141:5 @@ -142,7 +142,7 @@ LL | | None => None, LL | | }; | |_____^ | -help: try this +help: try | LL ~ Some(11).filter(|&x| { LL + println!("foo"); @@ -161,7 +161,7 @@ LL | | Some(x) ... | LL | | None => None, LL | | }; - | |_____^ help: try this: `Some(14).filter(|&x| unsafe { f(x) })` + | |_____^ help: try: `Some(14).filter(|&x| unsafe { f(x) })` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:195:13 @@ -173,7 +173,7 @@ LL | | if f(x) { Some(x) } else { None } LL | | }, LL | | None => None, LL | | }; - | |_____^ help: try this: `Some(15).filter(|&x| unsafe { f(x) })` + | |_____^ help: try: `Some(15).filter(|&x| unsafe { f(x) })` error: manual implementation of `Option::filter` --> $DIR/manual_filter.rs:205:12 @@ -185,7 +185,7 @@ LL | | if x % 2 == 0 { Some(x) } else { None } LL | | } else { LL | | None LL | | }; - | |_____^ help: try this: `{ Some(16).filter(|&x| x % 2 == 0) }` + | |_____^ help: try: `{ Some(16).filter(|&x| x % 2 == 0) }` error: aborting due to 15 previous errors diff --git a/tests/ui/manual_filter_map.fixed b/tests/ui/manual_filter_map.fixed index 4936dc9b2e01..9dd376df2b48 100644 --- a/tests/ui/manual_filter_map.fixed +++ b/tests/ui/manual_filter_map.fixed @@ -1,7 +1,8 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::manual_filter_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure +#![allow(clippy::useless_vec)] fn main() { // is_some(), unwrap() diff --git a/tests/ui/manual_filter_map.rs b/tests/ui/manual_filter_map.rs index 8c67e827b4c3..6dd1e066aebd 100644 --- a/tests/ui/manual_filter_map.rs +++ b/tests/ui/manual_filter_map.rs @@ -1,7 +1,8 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::manual_filter_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure +#![allow(clippy::useless_vec)] fn main() { // is_some(), unwrap() diff --git a/tests/ui/manual_filter_map.stderr b/tests/ui/manual_filter_map.stderr index 6e5bbe8f2aaf..882468b0f5f1 100644 --- a/tests/ui/manual_filter_map.stderr +++ b/tests/ui/manual_filter_map.stderr @@ -1,5 +1,5 @@ error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:8:19 + --> $DIR/manual_filter_map.rs:9:19 | LL | let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_opt(a))` @@ -7,19 +7,19 @@ LL | let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap = note: `-D clippy::manual-filter-map` implied by `-D warnings` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:11:19 + --> $DIR/manual_filter_map.rs:12:19 | LL | let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_opt(a))` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:14:19 + --> $DIR/manual_filter_map.rs:15:19 | LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_res(a).ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:17:10 + --> $DIR/manual_filter_map.rs:18:10 | LL | .filter(|&x| to_ref(to_opt(x)).is_some()) | __________^ @@ -27,7 +27,7 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:20:10 + --> $DIR/manual_filter_map.rs:21:10 | LL | .filter(|x| to_ref(to_opt(*x)).is_some()) | __________^ @@ -35,7 +35,7 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:24:10 + --> $DIR/manual_filter_map.rs:25:10 | LL | .filter(|&x| to_ref(to_res(x)).is_ok()) | __________^ @@ -43,7 +43,7 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:27:10 + --> $DIR/manual_filter_map.rs:28:10 | LL | .filter(|x| to_ref(to_res(*x)).is_ok()) | __________^ @@ -51,7 +51,7 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:33:27 + --> $DIR/manual_filter_map.rs:34:27 | LL | iter::>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` @@ -59,67 +59,67 @@ LL | iter::>().find(|x| x.is_some()).map(|x| x.cloned().unwrap() = note: `-D clippy::manual-find-map` implied by `-D warnings` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:34:28 + --> $DIR/manual_filter_map.rs:35:28 | LL | iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:35:31 + --> $DIR/manual_filter_map.rs:36:31 | LL | iter::<&Option>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:36:31 + --> $DIR/manual_filter_map.rs:37:31 | LL | iter::>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:38:30 + --> $DIR/manual_filter_map.rs:39:30 | LL | iter::>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:39:31 + --> $DIR/manual_filter_map.rs:40:31 | LL | iter::<&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:40:32 + --> $DIR/manual_filter_map.rs:41:32 | LL | iter::<&&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:41:31 + --> $DIR/manual_filter_map.rs:42:31 | LL | iter::>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:42:32 + --> $DIR/manual_filter_map.rs:43:32 | LL | iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:43:35 + --> $DIR/manual_filter_map.rs:44:35 | LL | iter::<&Result>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_filter_map.rs:44:35 + --> $DIR/manual_filter_map.rs:45:35 | LL | iter::>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:92:10 + --> $DIR/manual_filter_map.rs:93:10 | LL | .filter(|f| f.option_field.is_some()) | __________^ @@ -127,7 +127,7 @@ LL | | .map(|f| f.option_field.clone().unwrap()); | |_________________________________________________^ help: try: `filter_map(|f| f.option_field.clone())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:97:10 + --> $DIR/manual_filter_map.rs:98:10 | LL | .filter(|f| f.ref_field.is_some()) | __________^ @@ -135,7 +135,7 @@ LL | | .map(|f| f.ref_field.cloned().unwrap()); | |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.cloned())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:102:10 + --> $DIR/manual_filter_map.rs:103:10 | LL | .filter(|f| f.ref_field.is_some()) | __________^ @@ -143,7 +143,7 @@ LL | | .map(|f| f.ref_field.copied().unwrap()); | |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.copied())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:107:10 + --> $DIR/manual_filter_map.rs:108:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ @@ -151,7 +151,7 @@ LL | | .map(|f| f.result_field.clone().unwrap()); | |_________________________________________________^ help: try: `filter_map(|f| f.result_field.clone().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:112:10 + --> $DIR/manual_filter_map.rs:113:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ @@ -159,7 +159,7 @@ LL | | .map(|f| f.result_field.as_ref().unwrap()); | |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_ref().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:117:10 + --> $DIR/manual_filter_map.rs:118:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ @@ -167,7 +167,7 @@ LL | | .map(|f| f.result_field.as_deref().unwrap()); | |____________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:122:10 + --> $DIR/manual_filter_map.rs:123:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ @@ -175,7 +175,7 @@ LL | | .map(|f| f.result_field.as_mut().unwrap()); | |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_mut().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:127:10 + --> $DIR/manual_filter_map.rs:128:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ @@ -183,7 +183,7 @@ LL | | .map(|f| f.result_field.as_deref_mut().unwrap()); | |________________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref_mut().ok())` error: `filter(..).map(..)` can be simplified as `filter_map(..)` - --> $DIR/manual_filter_map.rs:132:10 + --> $DIR/manual_filter_map.rs:133:10 | LL | .filter(|f| f.result_field.is_ok()) | __________^ diff --git a/tests/ui/manual_find_fixable.fixed b/tests/ui/manual_find_fixable.fixed index 2bce6e624c90..9c5eb20c81cb 100644 --- a/tests/ui/manual_find_fixable.fixed +++ b/tests/ui/manual_find_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_find)] #![allow(unused)] #![allow(clippy::needless_return, clippy::uninlined_format_args)] diff --git a/tests/ui/manual_find_fixable.rs b/tests/ui/manual_find_fixable.rs index f5c6de37a257..7b670320ee33 100644 --- a/tests/ui/manual_find_fixable.rs +++ b/tests/ui/manual_find_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_find)] #![allow(unused)] #![allow(clippy::needless_return, clippy::uninlined_format_args)] diff --git a/tests/ui/manual_find_map.fixed b/tests/ui/manual_find_map.fixed index 54302beceff6..0c8eebf04b5c 100644 --- a/tests/ui/manual_find_map.fixed +++ b/tests/ui/manual_find_map.fixed @@ -1,7 +1,8 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::manual_find_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure +#![allow(clippy::useless_vec)] fn main() { // is_some(), unwrap() diff --git a/tests/ui/manual_find_map.rs b/tests/ui/manual_find_map.rs index afcc1825a9ac..b2feb48a839b 100644 --- a/tests/ui/manual_find_map.rs +++ b/tests/ui/manual_find_map.rs @@ -1,7 +1,8 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::manual_find_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure +#![allow(clippy::useless_vec)] fn main() { // is_some(), unwrap() diff --git a/tests/ui/manual_find_map.stderr b/tests/ui/manual_find_map.stderr index c1ac499f7c60..693a06bb5590 100644 --- a/tests/ui/manual_find_map.stderr +++ b/tests/ui/manual_find_map.stderr @@ -1,5 +1,5 @@ error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:8:19 + --> $DIR/manual_find_map.rs:9:19 | LL | let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_opt(a))` @@ -7,19 +7,19 @@ LL | let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap() = note: `-D clippy::manual-find-map` implied by `-D warnings` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:11:19 + --> $DIR/manual_find_map.rs:12:19 | LL | let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_opt(a))` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:14:19 + --> $DIR/manual_find_map.rs:15:19 | LL | let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_res(a).ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:17:10 + --> $DIR/manual_find_map.rs:18:10 | LL | .find(|&x| to_ref(to_opt(x)).is_some()) | __________^ @@ -27,7 +27,7 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:20:10 + --> $DIR/manual_find_map.rs:21:10 | LL | .find(|x| to_ref(to_opt(*x)).is_some()) | __________^ @@ -35,7 +35,7 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:24:10 + --> $DIR/manual_find_map.rs:25:10 | LL | .find(|&x| to_ref(to_res(x)).is_ok()) | __________^ @@ -43,7 +43,7 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:27:10 + --> $DIR/manual_find_map.rs:28:10 | LL | .find(|x| to_ref(to_res(*x)).is_ok()) | __________^ @@ -51,91 +51,91 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap()); | |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:33:26 + --> $DIR/manual_find_map.rs:34:26 | LL | iter::>().find(|x| x.is_some()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x)` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:34:27 + --> $DIR/manual_find_map.rs:35:27 | LL | iter::<&Option>().find(|x| x.is_some()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| *x)` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:35:28 + --> $DIR/manual_find_map.rs:36:28 | LL | iter::<&&Option>().find(|x| x.is_some()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| **x)` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:36:27 + --> $DIR/manual_find_map.rs:37:27 | LL | iter::>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:37:28 + --> $DIR/manual_find_map.rs:38:28 | LL | iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:38:31 + --> $DIR/manual_find_map.rs:39:31 | LL | iter::<&Option>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:39:31 + --> $DIR/manual_find_map.rs:40:31 | LL | iter::>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:41:30 + --> $DIR/manual_find_map.rs:42:30 | LL | iter::>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:42:31 + --> $DIR/manual_find_map.rs:43:31 | LL | iter::<&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:43:32 + --> $DIR/manual_find_map.rs:44:32 | LL | iter::<&&Result>().find(|x| x.is_ok()).map(|x| x.unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:44:31 + --> $DIR/manual_find_map.rs:45:31 | LL | iter::>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:45:32 + --> $DIR/manual_find_map.rs:46:32 | LL | iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:46:35 + --> $DIR/manual_find_map.rs:47:35 | LL | iter::<&Result>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:47:35 + --> $DIR/manual_find_map.rs:48:35 | LL | iter::>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:95:10 + --> $DIR/manual_find_map.rs:96:10 | LL | .find(|f| f.option_field.is_some()) | __________^ @@ -143,7 +143,7 @@ LL | | .map(|f| f.option_field.clone().unwrap()); | |_________________________________________________^ help: try: `find_map(|f| f.option_field.clone())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:100:10 + --> $DIR/manual_find_map.rs:101:10 | LL | .find(|f| f.ref_field.is_some()) | __________^ @@ -151,7 +151,7 @@ LL | | .map(|f| f.ref_field.cloned().unwrap()); | |_______________________________________________^ help: try: `find_map(|f| f.ref_field.cloned())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:105:10 + --> $DIR/manual_find_map.rs:106:10 | LL | .find(|f| f.ref_field.is_some()) | __________^ @@ -159,7 +159,7 @@ LL | | .map(|f| f.ref_field.copied().unwrap()); | |_______________________________________________^ help: try: `find_map(|f| f.ref_field.copied())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:110:10 + --> $DIR/manual_find_map.rs:111:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ @@ -167,7 +167,7 @@ LL | | .map(|f| f.result_field.clone().unwrap()); | |_________________________________________________^ help: try: `find_map(|f| f.result_field.clone().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:115:10 + --> $DIR/manual_find_map.rs:116:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ @@ -175,7 +175,7 @@ LL | | .map(|f| f.result_field.as_ref().unwrap()); | |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_ref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:120:10 + --> $DIR/manual_find_map.rs:121:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ @@ -183,7 +183,7 @@ LL | | .map(|f| f.result_field.as_deref().unwrap()); | |____________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:125:10 + --> $DIR/manual_find_map.rs:126:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ @@ -191,7 +191,7 @@ LL | | .map(|f| f.result_field.as_mut().unwrap()); | |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_mut().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:130:10 + --> $DIR/manual_find_map.rs:131:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ @@ -199,7 +199,7 @@ LL | | .map(|f| f.result_field.as_deref_mut().unwrap()); | |________________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref_mut().ok())` error: `find(..).map(..)` can be simplified as `find_map(..)` - --> $DIR/manual_find_map.rs:135:10 + --> $DIR/manual_find_map.rs:136:10 | LL | .find(|f| f.result_field.is_ok()) | __________^ diff --git a/tests/ui/manual_float_methods.rs b/tests/ui/manual_float_methods.rs new file mode 100644 index 000000000000..af9076cfb71f --- /dev/null +++ b/tests/ui/manual_float_methods.rs @@ -0,0 +1,55 @@ +//@aux-build:proc_macros.rs:proc-macro +#![allow(clippy::needless_if, unused)] +#![warn(clippy::manual_is_infinite, clippy::manual_is_finite)] +#![feature(inline_const)] + +#[macro_use] +extern crate proc_macros; + +const INFINITE: f32 = f32::INFINITY; +const NEG_INFINITE: f32 = f32::NEG_INFINITY; + +fn fn_test() -> f64 { + f64::NEG_INFINITY +} + +fn fn_test_not_inf() -> f64 { + 112.0 +} + +fn main() { + let x = 1.0f32; + if x == f32::INFINITY || x == f32::NEG_INFINITY {} + if x != f32::INFINITY && x != f32::NEG_INFINITY {} + if x == INFINITE || x == NEG_INFINITE {} + if x != INFINITE && x != NEG_INFINITE {} + let x = 1.0f64; + if x == f64::INFINITY || x == f64::NEG_INFINITY {} + if x != f64::INFINITY && x != f64::NEG_INFINITY {} + // Don't lint + if x.is_infinite() {} + if x.is_finite() {} + if x.abs() < f64::INFINITY {} + if f64::INFINITY > x.abs() {} + if f64::abs(x) < f64::INFINITY {} + if f64::INFINITY > f64::abs(x) {} + // Is not evaluated by `clippy_utils::constant` + if x != f64::INFINITY && x != fn_test() {} + // Not -inf + if x != f64::INFINITY && x != fn_test_not_inf() {} + const X: f64 = 1.0f64; + // Will be linted if `const_float_classify` is enabled + if const { X == f64::INFINITY || X == f64::NEG_INFINITY } {} + if const { X != f64::INFINITY && X != f64::NEG_INFINITY } {} + external! { + let x = 1.0; + if x == f32::INFINITY || x == f32::NEG_INFINITY {} + if x != f32::INFINITY && x != f32::NEG_INFINITY {} + } + with_span! { + span + let x = 1.0; + if x == f32::INFINITY || x == f32::NEG_INFINITY {} + if x != f32::INFINITY && x != f32::NEG_INFINITY {} + } +} diff --git a/tests/ui/manual_float_methods.stderr b/tests/ui/manual_float_methods.stderr new file mode 100644 index 000000000000..a56118b316ae --- /dev/null +++ b/tests/ui/manual_float_methods.stderr @@ -0,0 +1,80 @@ +error: manually checking if a float is infinite + --> $DIR/manual_float_methods.rs:22:8 + | +LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` + | + = note: `-D clippy::manual-is-infinite` implied by `-D warnings` + +error: manually checking if a float is finite + --> $DIR/manual_float_methods.rs:23:8 + | +LL | if x != f32::INFINITY && x != f32::NEG_INFINITY {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::manual-is-finite` implied by `-D warnings` +help: use the dedicated method instead + | +LL | if x.is_finite() {} + | ~~~~~~~~~~~~~ +help: this will alter how it handles NaN; if that is a problem, use instead + | +LL | if x.is_finite() || x.is_nan() {} + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: or, for conciseness + | +LL | if !x.is_infinite() {} + | ~~~~~~~~~~~~~~~~ + +error: manually checking if a float is infinite + --> $DIR/manual_float_methods.rs:24:8 + | +LL | if x == INFINITE || x == NEG_INFINITE {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` + +error: manually checking if a float is finite + --> $DIR/manual_float_methods.rs:25:8 + | +LL | if x != INFINITE && x != NEG_INFINITE {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use the dedicated method instead + | +LL | if x.is_finite() {} + | ~~~~~~~~~~~~~ +help: this will alter how it handles NaN; if that is a problem, use instead + | +LL | if x.is_finite() || x.is_nan() {} + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: or, for conciseness + | +LL | if !x.is_infinite() {} + | ~~~~~~~~~~~~~~~~ + +error: manually checking if a float is infinite + --> $DIR/manual_float_methods.rs:27:8 + | +LL | if x == f64::INFINITY || x == f64::NEG_INFINITY {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` + +error: manually checking if a float is finite + --> $DIR/manual_float_methods.rs:28:8 + | +LL | if x != f64::INFINITY && x != f64::NEG_INFINITY {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use the dedicated method instead + | +LL | if x.is_finite() {} + | ~~~~~~~~~~~~~ +help: this will alter how it handles NaN; if that is a problem, use instead + | +LL | if x.is_finite() || x.is_nan() {} + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: or, for conciseness + | +LL | if !x.is_infinite() {} + | ~~~~~~~~~~~~~~~~ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/manual_instant_elapsed.fixed b/tests/ui/manual_instant_elapsed.fixed index 85a91543c893..55073c3b57cf 100644 --- a/tests/ui/manual_instant_elapsed.fixed +++ b/tests/ui/manual_instant_elapsed.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_instant_elapsed)] #![allow(clippy::unnecessary_operation)] #![allow(clippy::unchecked_duration_subtraction)] diff --git a/tests/ui/manual_instant_elapsed.rs b/tests/ui/manual_instant_elapsed.rs index c98cb15b9164..c9029a049408 100644 --- a/tests/ui/manual_instant_elapsed.rs +++ b/tests/ui/manual_instant_elapsed.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_instant_elapsed)] #![allow(clippy::unnecessary_operation)] #![allow(clippy::unchecked_duration_subtraction)] diff --git a/tests/ui/manual_is_ascii_check.fixed b/tests/ui/manual_is_ascii_check.fixed index 5b2b44c2fdb2..87e866586683 100644 --- a/tests/ui/manual_is_ascii_check.fixed +++ b/tests/ui/manual_is_ascii_check.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, dead_code)] #![warn(clippy::manual_is_ascii_check)] diff --git a/tests/ui/manual_is_ascii_check.rs b/tests/ui/manual_is_ascii_check.rs index c9433f33a1b6..931f0f20276b 100644 --- a/tests/ui/manual_is_ascii_check.rs +++ b/tests/ui/manual_is_ascii_check.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, dead_code)] #![warn(clippy::manual_is_ascii_check)] diff --git a/tests/ui/manual_let_else.rs b/tests/ui/manual_let_else.rs index d175597a44a6..830115c3c14c 100644 --- a/tests/ui/manual_let_else.rs +++ b/tests/ui/manual_let_else.rs @@ -4,10 +4,17 @@ clippy::unused_unit, clippy::let_unit_value, clippy::match_single_binding, - clippy::never_loop + clippy::never_loop, + clippy::needless_if )] #![warn(clippy::manual_let_else)] +enum Variant { + A(usize, usize), + B(usize), + C, +} + fn g() -> Option<()> { None } @@ -121,8 +128,8 @@ fn fire() { return; }; - // Tuples supported for the identity block and pattern - let v = if let (Some(v_some), w_some) = (g(), 0) { + // Tuples supported with multiple bindings + let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) { (w_some, v_some) } else { return; @@ -135,6 +142,82 @@ fn fire() { }; } create_binding_if_some!(w, g()); + + fn e() -> Variant { + Variant::A(0, 0) + } + +<<<<<<< HEAD +<<<<<<< HEAD + let v = if let Variant::A(a, 0) = e() { a } else { return }; + + // `mut v` is inserted into the pattern + let mut v = if let Variant::B(b) = e() { b } else { return }; + + // Nesting works + let nested = Ok(Some(e())); + let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested { + b + } else { + return; + }; + // dot dot works + let v = if let Variant::A(.., a) = e() { a } else { return }; + + // () is preserved: a bit of an edge case but make sure it stays around + let w = if let (Some(v), ()) = (g(), ()) { v } else { return }; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> f53840270 (Support struct patterns) + + // Tuple structs work + let w = if let Some(S { v: x }) = Some(S { v: 0 }) { + x + } else { + return; + }; + + // Field init shorthand is suggested + let v = if let Some(S { v: x }) = Some(S { v: 0 }) { + x + } else { + return; + }; + + // Multi-field structs also work + let (x, S { v }, w) = if let Some(U { v, w, x }) = None::>> { + (x, v, w) + } else { + return; + }; +<<<<<<< HEAD +======= + // Should not be renamed + let v = if let Variant::A(a, 0) = e() { a } else { return }; + // Should be renamed + let v = if let Variant::B(b) = e() { b } else { return }; +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + let v = if let Variant::A(a, 0) = e() { a } else { return }; + + // `mut v` is inserted into the pattern + let mut v = if let Variant::B(b) = e() { b } else { return }; + + // Nesting works + let nested = Ok(Some(e())); + let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested { + b + } else { + return; + }; + // dot dot works + let v = if let Variant::A(.., a) = e() { a } else { return }; +>>>>>>> ef38662d0 (Some improvements to the manual_let_else lint suggestions) +======= +>>>>>>> 86d57b7bd (Support multi-binding situations as well as tuple patterns) +======= +>>>>>>> f53840270 (Support struct patterns) } fn not_fire() { @@ -259,4 +342,34 @@ fn not_fire() { }; 1 }; + + // This would require creation of a suggestion of the form + // let v @ (Some(_), _) = (...) else { return }; + // Which is too advanced for our code, so we just bail. + let v = if let (Some(v_some), w_some) = (g(), 0) { + (w_some, v_some) + } else { + return; + }; +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> f53840270 (Support struct patterns) +struct S { + v: T, +} + +struct U { + v: T, + w: T, + x: T, +<<<<<<< HEAD +======= +struct S { + v: u32, +>>>>>>> 86d57b7bd (Support multi-binding situations as well as tuple patterns) +======= +>>>>>>> f53840270 (Support struct patterns) } diff --git a/tests/ui/manual_let_else.stderr b/tests/ui/manual_let_else.stderr index 52aac6bc673d..329f812db3fd 100644 --- a/tests/ui/manual_let_else.stderr +++ b/tests/ui/manual_let_else.stderr @@ -1,13 +1,29 @@ error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:18:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:25:5 +======= + --> $DIR/manual_let_else.rs:24:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:25:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | let v = if let Some(v_some) = g() { v_some } else { return }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v_some) = g() else { return };` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };` | = note: `-D clippy::manual-let-else` implied by `-D warnings` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:19:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:26:5 +======= + --> $DIR/manual_let_else.rs:25:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:26:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / let v = if let Some(v_some) = g() { LL | | v_some @@ -18,13 +34,21 @@ LL | | }; | help: consider writing | -LL ~ let Some(v_some) = g() else { +LL ~ let Some(v) = g() else { LL + return; LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:25:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:32:5 +======= + --> $DIR/manual_let_else.rs:31:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:32:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / let v = if let Some(v) = g() { LL | | // Blocks around the identity should have no impact @@ -45,25 +69,57 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:38:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:45:9 +======= + --> $DIR/manual_let_else.rs:44:9 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:45:9 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | let v = if let Some(v_some) = g() { v_some } else { continue }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v_some) = g() else { continue };` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { continue };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:39:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:46:9 +======= + --> $DIR/manual_let_else.rs:45:9 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:46:9 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | let v = if let Some(v_some) = g() { v_some } else { break }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v_some) = g() else { break };` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { break };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:43:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:50:5 +======= + --> $DIR/manual_let_else.rs:49:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:50:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | let v = if let Some(v_some) = g() { v_some } else { panic!() }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v_some) = g() else { panic!() };` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { panic!() };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:46:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:53:5 +======= + --> $DIR/manual_let_else.rs:52:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:53:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / let v = if let Some(v_some) = g() { LL | | v_some @@ -74,13 +130,21 @@ LL | | }; | help: consider writing | -LL ~ let Some(v_some) = g() else { +LL ~ let Some(v) = g() else { LL + std::process::abort() LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:53:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:60:5 +======= + --> $DIR/manual_let_else.rs:59:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:60:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / let v = if let Some(v_some) = g() { LL | | v_some @@ -91,13 +155,21 @@ LL | | }; | help: consider writing | -LL ~ let Some(v_some) = g() else { +LL ~ let Some(v) = g() else { LL + if true { return } else { panic!() } LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:60:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:67:5 +======= + --> $DIR/manual_let_else.rs:66:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:67:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / let v = if let Some(v_some) = g() { LL | | v_some @@ -109,14 +181,22 @@ LL | | }; | help: consider writing | -LL ~ let Some(v_some) = g() else { +LL ~ let Some(v) = g() else { LL + if true {} LL + panic!(); LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:70:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:77:5 +======= + --> $DIR/manual_let_else.rs:76:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:77:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / let v = if let Some(v_some) = g() { LL | | v_some @@ -129,7 +209,7 @@ LL | | }; | help: consider writing | -LL ~ let Some(v_some) = g() else { +LL ~ let Some(v) = g() else { LL + match () { LL + _ if panic!() => {}, LL + _ => panic!(), @@ -138,13 +218,29 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:80:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:87:5 +======= + --> $DIR/manual_let_else.rs:86:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:87:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | let v = if let Some(v_some) = g() { v_some } else { if panic!() {} }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v_some) = g() else { if panic!() {} };` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { if panic!() {} };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:83:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:90:5 +======= + --> $DIR/manual_let_else.rs:89:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:90:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / let v = if let Some(v_some) = g() { LL | | v_some @@ -157,7 +253,7 @@ LL | | }; | help: consider writing | -LL ~ let Some(v_some) = g() else { +LL ~ let Some(v) = g() else { LL + match panic!() { LL + _ => {}, LL + } @@ -165,7 +261,15 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:92:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:99:5 +======= + --> $DIR/manual_let_else.rs:98:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:99:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / let v = if let Some(v_some) = g() { LL | | v_some @@ -178,7 +282,7 @@ LL | | }; | help: consider writing | -LL ~ let Some(v_some) = g() else { if true { +LL ~ let Some(v) = g() else { if true { LL + return; LL + } else { LL + panic!("diverge"); @@ -186,7 +290,15 @@ LL + } }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:101:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:108:5 +======= + --> $DIR/manual_let_else.rs:107:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:108:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / let v = if let Some(v_some) = g() { LL | | v_some @@ -199,7 +311,7 @@ LL | | }; | help: consider writing | -LL ~ let Some(v_some) = g() else { +LL ~ let Some(v) = g() else { LL + match (g(), g()) { LL + (Some(_), None) => return, LL + (None, Some(_)) => { @@ -215,7 +327,15 @@ LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:118:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:125:5 +======= + --> $DIR/manual_let_else.rs:124:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:125:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) { LL | | v_some @@ -226,15 +346,23 @@ LL | | }; | help: consider writing | -LL ~ let Some(v_some) = g().map(|v| (v, 42)) else { +LL ~ let Some((v, w)) = g().map(|v| (v, 42)) else { LL + return; LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:125:5 - | -LL | / let v = if let (Some(v_some), w_some) = (g(), 0) { +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:132:5 +======= + --> $DIR/manual_let_else.rs:131:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:132:5 +>>>>>>> 26f50395b (Add `needless_if` lint) + | +LL | / let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) { LL | | (w_some, v_some) LL | | } else { LL | | return; @@ -243,16 +371,24 @@ LL | | }; | help: consider writing | -LL ~ let (Some(v_some), w_some) = (g(), 0) else { +LL ~ let (Some(S { v }), w) = (g().map(|_| S { v: 0 }), 0) else { LL + return; LL + }; | error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:134:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:141:13 +======= + --> $DIR/manual_let_else.rs:140:13 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:141:13 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | let $n = if let Some(v) = $e { v } else { return }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some($n) = g() else { return };` ... LL | create_binding_if_some!(w, g()); | ------------------------------- in this macro invocation @@ -260,13 +396,249 @@ LL | create_binding_if_some!(w, g()); = note: this error originates in the macro `create_binding_if_some` (in Nightly builds, run with -Z macro-backtrace for more info) error: this could be rewritten as `let...else` - --> $DIR/manual_let_else.rs:247:5 + --> $DIR/manual_let_else.rs:150:5 + | +LL | let v = if let Variant::A(a, 0) = e() { a } else { return }; +<<<<<<< HEAD +<<<<<<< HEAD + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(v, 0) = e() else { return };` + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:153:5 +<<<<<<< HEAD + | +LL | let mut v = if let Variant::B(b) = e() { b } else { return }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::B(mut v) = e() else { return };` + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:157:5 + | +LL | / let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested { +LL | | b +LL | | } else { +LL | | return; +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let (Ok(Some(Variant::B(v))) | Err(Some(Variant::A(v, _)))) = nested else { +LL + return; +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:163:5 + | +LL | let v = if let Variant::A(.., a) = e() { a } else { return }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(.., v) = e() else { return };` + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:166:5 + | +LL | let w = if let (Some(v), ()) = (g(), ()) { v } else { return }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let (Some(w), ()) = (g(), ()) else { return };` + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:169:5 + | +LL | / let w = if let Some(S { v: x }) = Some(S { v: 0 }) { +LL | | x +LL | | } else { +LL | | return; +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let Some(S { v: w }) = Some(S { v: 0 }) else { +LL + return; +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:176:5 + | +LL | / let v = if let Some(S { v: x }) = Some(S { v: 0 }) { +LL | | x +LL | | } else { +LL | | return; +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let Some(S { v }) = Some(S { v: 0 }) else { +LL + return; +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:183:5 + | +LL | / let (x, S { v }, w) = if let Some(U { v, w, x }) = None::>> { +LL | | (x, v, w) +LL | | } else { +LL | | return; +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let Some(U { v: S { v }, w, x }) = None::>> else { +LL + return; +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:297:5 +======= + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(a, 0) = e() else { return };` +======= + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(v, 0) = e() else { return };` +>>>>>>> ef38662d0 (Some improvements to the manual_let_else lint suggestions) + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:152:5 +======= +>>>>>>> 26f50395b (Add `needless_if` lint) + | +LL | let mut v = if let Variant::B(b) = e() { b } else { return }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::B(mut v) = e() else { return };` + +error: this could be rewritten as `let...else` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:262:5 +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= + --> $DIR/manual_let_else.rs:156:5 +======= + --> $DIR/manual_let_else.rs:157:5 +>>>>>>> 26f50395b (Add `needless_if` lint) + | +LL | / let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested { +LL | | b +LL | | } else { +LL | | return; +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let (Ok(Some(Variant::B(v))) | Err(Some(Variant::A(v, _)))) = nested else { +LL + return; +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:163:5 + | +LL | let v = if let Variant::A(.., a) = e() { a } else { return }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(.., v) = e() else { return };` + +error: this could be rewritten as `let...else` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:272:5 +>>>>>>> ef38662d0 (Some improvements to the manual_let_else lint suggestions) +======= + --> $DIR/manual_let_else.rs:165:5 +======= + --> $DIR/manual_let_else.rs:166:5 +>>>>>>> 26f50395b (Add `needless_if` lint) + | +LL | let w = if let (Some(v), ()) = (g(), ()) { v } else { return }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let (Some(w), ()) = (g(), ()) else { return };` + +error: this could be rewritten as `let...else` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:275:5 +>>>>>>> 86d57b7bd (Support multi-binding situations as well as tuple patterns) +======= + --> $DIR/manual_let_else.rs:168:5 +======= + --> $DIR/manual_let_else.rs:169:5 +>>>>>>> 26f50395b (Add `needless_if` lint) + | +LL | / let w = if let Some(S { v: x }) = Some(S { v: 0 }) { +LL | | x +LL | | } else { +LL | | return; +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let Some(S { v: w }) = Some(S { v: 0 }) else { +LL + return; +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:176:5 + | +LL | / let v = if let Some(S { v: x }) = Some(S { v: 0 }) { +LL | | x +LL | | } else { +LL | | return; +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let Some(S { v }) = Some(S { v: 0 }) else { +LL + return; +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else.rs:183:5 + | +LL | / let (x, S { v }, w) = if let Some(U { v, w, x }) = None::>> { +LL | | (x, v, w) +LL | | } else { +LL | | return; +LL | | }; + | |______^ + | +help: consider writing + | +LL ~ let Some(U { v: S { v }, w, x }) = None::>> else { +LL + return; +LL + }; + | + +error: this could be rewritten as `let...else` +<<<<<<< HEAD + --> $DIR/manual_let_else.rs:296:5 +>>>>>>> f53840270 (Support struct patterns) +======= + --> $DIR/manual_let_else.rs:297:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / let _ = match ff { LL | | Some(value) => value, LL | | _ => macro_call!(), LL | | }; - | |______^ help: consider writing: `let Some(value) = ff else { macro_call!() };` + | |______^ help: consider writing: `let Some(_) = ff else { macro_call!() };` -error: aborting due to 18 previous errors +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 26 previous errors +======= +error: aborting due to 20 previous errors +>>>>>>> 07c8c50a4 (Avoid renaming for TupleStruct with multiple arguments) +======= +error: aborting due to 22 previous errors +>>>>>>> ef38662d0 (Some improvements to the manual_let_else lint suggestions) +======= +error: aborting due to 23 previous errors +>>>>>>> 86d57b7bd (Support multi-binding situations as well as tuple patterns) +======= +error: aborting due to 26 previous errors +>>>>>>> f53840270 (Support struct patterns) diff --git a/tests/ui/manual_let_else_match.rs b/tests/ui/manual_let_else_match.rs index 73b746791259..20ca6ed979c1 100644 --- a/tests/ui/manual_let_else_match.rs +++ b/tests/ui/manual_let_else_match.rs @@ -1,5 +1,19 @@ #![allow(unused_braces, unused_variables, dead_code)] -#![allow(clippy::collapsible_else_if, clippy::let_unit_value)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> e9ced1251 (Rename the lint) +#![allow( + clippy::collapsible_else_if, + clippy::let_unit_value, + clippy::redundant_at_rest_pattern +)] +<<<<<<< HEAD +======= +#![allow(clippy::collapsible_else_if, clippy::let_unit_value, clippy::redundant_rest_pattern)] +>>>>>>> 9a8347ded (New lint [`redundant_rest_pattern`]) +======= +>>>>>>> e9ced1251 (Rename the lint) #![warn(clippy::manual_let_else)] // Ensure that we don't conflict with match -> if let lints #![warn(clippy::single_match_else, clippy::single_match)] @@ -68,7 +82,20 @@ fn fire() { let f = Variant::Bar(1); let _value = match f { - Variant::Bar(_) | Variant::Baz(_) => (), + Variant::Bar(v) | Variant::Baz(v) => v, +<<<<<<< HEAD + _ => return, + }; + + let _value = match Some(build_enum()) { + Some(Variant::Bar(v) | Variant::Baz(v)) => v, +======= +>>>>>>> ef38662d0 (Some improvements to the manual_let_else lint suggestions) + _ => return, + }; + + let _value = match Some(build_enum()) { + Some(Variant::Bar(v) | Variant::Baz(v)) => v, _ => return, }; diff --git a/tests/ui/manual_let_else_match.stderr b/tests/ui/manual_let_else_match.stderr index 7abaa0b85d23..c066958fe5fd 100644 --- a/tests/ui/manual_let_else_match.stderr +++ b/tests/ui/manual_let_else_match.stderr @@ -1,25 +1,25 @@ error: this could be rewritten as `let...else` - --> $DIR/manual_let_else_match.rs:32:5 + --> $DIR/manual_let_else_match.rs:36:5 | LL | / let v = match g() { LL | | Some(v_some) => v_some, LL | | None => return, LL | | }; - | |______^ help: consider writing: `let Some(v_some) = g() else { return };` + | |______^ help: consider writing: `let Some(v) = g() else { return };` | = note: `-D clippy::manual-let-else` implied by `-D warnings` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else_match.rs:37:5 + --> $DIR/manual_let_else_match.rs:41:5 | LL | / let v = match g() { LL | | Some(v_some) => v_some, LL | | _ => return, LL | | }; - | |______^ help: consider writing: `let Some(v_some) = g() else { return };` + | |______^ help: consider writing: `let Some(v) = g() else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else_match.rs:44:9 + --> $DIR/manual_let_else_match.rs:48:9 | LL | / let v = match h() { LL | | (Some(v), None) | (None, Some(v)) => v, @@ -28,7 +28,7 @@ LL | | }; | |__________^ help: consider writing: `let ((Some(v), None) | (None, Some(v))) = h() else { continue };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else_match.rs:49:9 + --> $DIR/manual_let_else_match.rs:53:9 | LL | / let v = match build_enum() { LL | | Variant::Bar(v) | Variant::Baz(v) => v, @@ -37,7 +37,7 @@ LL | | }; | |__________^ help: consider writing: `let (Variant::Bar(v) | Variant::Baz(v)) = build_enum() else { continue };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else_match.rs:57:5 + --> $DIR/manual_let_else_match.rs:61:5 | LL | / let v = match f() { LL | | Ok(v) => v, @@ -46,7 +46,7 @@ LL | | }; | |______^ help: consider writing: `let Ok(v) = f() else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else_match.rs:63:5 + --> $DIR/manual_let_else_match.rs:67:5 | LL | / let v = match f().map_err(|_| ()) { LL | | Ok(v) => v, @@ -55,16 +55,41 @@ LL | | }; | |______^ help: consider writing: `let Ok(v) = f().map_err(|_| ()) else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else_match.rs:70:5 + --> $DIR/manual_let_else_match.rs:74:5 | LL | / let _value = match f { -LL | | Variant::Bar(_) | Variant::Baz(_) => (), +LL | | Variant::Bar(v) | Variant::Baz(v) => v, LL | | _ => return, LL | | }; - | |______^ help: consider writing: `let (Variant::Bar(_) | Variant::Baz(_)) = f else { return };` + | |______^ help: consider writing: `let (Variant::Bar(_value) | Variant::Baz(_value)) = f else { return };` error: this could be rewritten as `let...else` - --> $DIR/manual_let_else_match.rs:76:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else_match.rs:79:5 +======= + --> $DIR/manual_let_else_match.rs:75:5 +>>>>>>> 0a7366897 (manual_let_else: only add () around PatKind::Or at the top level) +======= + --> $DIR/manual_let_else_match.rs:79:5 +>>>>>>> e9ced1251 (Rename the lint) + | +LL | / let _value = match Some(build_enum()) { +LL | | Some(Variant::Bar(v) | Variant::Baz(v)) => v, +LL | | _ => return, +LL | | }; + | |______^ help: consider writing: `let Some(Variant::Bar(_value) | Variant::Baz(_value)) = Some(build_enum()) else { return };` + +error: this could be rewritten as `let...else` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_let_else_match.rs:85:5 +======= + --> $DIR/manual_let_else_match.rs:81:5 +>>>>>>> 0a7366897 (manual_let_else: only add () around PatKind::Or at the top level) +======= + --> $DIR/manual_let_else_match.rs:85:5 +>>>>>>> e9ced1251 (Rename the lint) | LL | / let data = match data.as_slice() { LL | | [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data, @@ -72,5 +97,5 @@ LL | | _ => return, LL | | }; | |______^ help: consider writing: `let ([data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0]) = data.as_slice() else { return };` -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors diff --git a/tests/ui/manual_let_else_question_mark.fixed b/tests/ui/manual_let_else_question_mark.fixed new file mode 100644 index 000000000000..02308bc7c4c1 --- /dev/null +++ b/tests/ui/manual_let_else_question_mark.fixed @@ -0,0 +1,63 @@ +//@run-rustfix +#![allow(unused_braces, unused_variables, dead_code)] +#![allow( + clippy::collapsible_else_if, + clippy::unused_unit, + clippy::let_unit_value, + clippy::match_single_binding, + clippy::never_loop +)] +#![warn(clippy::manual_let_else, clippy::question_mark)] + +enum Variant { + A(usize, usize), + B(usize), + C, +} + +fn g() -> Option<(u8, u8)> { + None +} + +fn e() -> Variant { + Variant::A(0, 0) +} + +fn main() {} + +fn foo() -> Option<()> { + // Fire here, normal case + let v = g()?; + + // Don't fire here, the pattern is refutable + let Variant::A(v, w) = e() else { return None }; + + // Fire here, the pattern is irrefutable + let (v, w) = g()?; + + // Don't fire manual_let_else in this instance: question mark can be used instead. + let v = g()?; + + // Do fire manual_let_else in this instance: question mark cannot be used here due to the return + // body. + let Some(v) = g() else { + return Some(()); + }; + + // Here we could also fire the question_mark lint, but we don't (as it's a match and not an if let). + // So we still emit manual_let_else here. For the *resulting* code, we *do* emit the question_mark + // lint, so for rustfix reasons, we allow the question_mark lint here. + #[allow(clippy::question_mark)] + { + let Some(v) = g() else { return None }; + } + + // This is a copy of the case above where we'd fire the question_mark lint, but here we have allowed + // it. Make sure that manual_let_else is fired as the fallback. + #[allow(clippy::question_mark)] + { + let Some(v) = g() else { return None }; + } + + Some(()) +} diff --git a/tests/ui/manual_let_else_question_mark.rs b/tests/ui/manual_let_else_question_mark.rs new file mode 100644 index 000000000000..9c7ad386dc99 --- /dev/null +++ b/tests/ui/manual_let_else_question_mark.rs @@ -0,0 +1,68 @@ +//@run-rustfix +#![allow(unused_braces, unused_variables, dead_code)] +#![allow( + clippy::collapsible_else_if, + clippy::unused_unit, + clippy::let_unit_value, + clippy::match_single_binding, + clippy::never_loop +)] +#![warn(clippy::manual_let_else, clippy::question_mark)] + +enum Variant { + A(usize, usize), + B(usize), + C, +} + +fn g() -> Option<(u8, u8)> { + None +} + +fn e() -> Variant { + Variant::A(0, 0) +} + +fn main() {} + +fn foo() -> Option<()> { + // Fire here, normal case + let Some(v) = g() else { return None }; + + // Don't fire here, the pattern is refutable + let Variant::A(v, w) = e() else { return None }; + + // Fire here, the pattern is irrefutable + let Some((v, w)) = g() else { return None }; + + // Don't fire manual_let_else in this instance: question mark can be used instead. + let v = if let Some(v_some) = g() { v_some } else { return None }; + + // Do fire manual_let_else in this instance: question mark cannot be used here due to the return + // body. + let v = if let Some(v_some) = g() { + v_some + } else { + return Some(()); + }; + + // Here we could also fire the question_mark lint, but we don't (as it's a match and not an if let). + // So we still emit manual_let_else here. For the *resulting* code, we *do* emit the question_mark + // lint, so for rustfix reasons, we allow the question_mark lint here. + #[allow(clippy::question_mark)] + { + let v = match g() { + Some(v_some) => v_some, + _ => return None, + }; + } + + // This is a copy of the case above where we'd fire the question_mark lint, but here we have allowed + // it. Make sure that manual_let_else is fired as the fallback. + #[allow(clippy::question_mark)] + { + let v = if let Some(v_some) = g() { v_some } else { return None }; + } + + Some(()) +} diff --git a/tests/ui/manual_let_else_question_mark.stderr b/tests/ui/manual_let_else_question_mark.stderr new file mode 100644 index 000000000000..d7d2e127ea3f --- /dev/null +++ b/tests/ui/manual_let_else_question_mark.stderr @@ -0,0 +1,55 @@ +error: this `let...else` may be rewritten with the `?` operator + --> $DIR/manual_let_else_question_mark.rs:30:5 + | +LL | let Some(v) = g() else { return None }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `let v = g()?;` + | + = note: `-D clippy::question-mark` implied by `-D warnings` + +error: this `let...else` may be rewritten with the `?` operator + --> $DIR/manual_let_else_question_mark.rs:36:5 + | +LL | let Some((v, w)) = g() else { return None }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `let (v, w) = g()?;` + +error: this block may be rewritten with the `?` operator + --> $DIR/manual_let_else_question_mark.rs:39:13 + | +LL | let v = if let Some(v_some) = g() { v_some } else { return None }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `g()?` + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else_question_mark.rs:43:5 + | +LL | / let v = if let Some(v_some) = g() { +LL | | v_some +LL | | } else { +LL | | return Some(()); +LL | | }; + | |______^ + | + = note: `-D clippy::manual-let-else` implied by `-D warnings` +help: consider writing + | +LL ~ let Some(v) = g() else { +LL + return Some(()); +LL + }; + | + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else_question_mark.rs:54:9 + | +LL | / let v = match g() { +LL | | Some(v_some) => v_some, +LL | | _ => return None, +LL | | }; + | |__________^ help: consider writing: `let Some(v) = g() else { return None };` + +error: this could be rewritten as `let...else` + --> $DIR/manual_let_else_question_mark.rs:64:9 + | +LL | let v = if let Some(v_some) = g() { v_some } else { return None }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return None };` + +error: aborting due to 6 previous errors + diff --git a/tests/ui/manual_main_separator_str.fixed b/tests/ui/manual_main_separator_str.fixed index 50f46d6b3550..7e7da8f20bb3 100644 --- a/tests/ui/manual_main_separator_str.fixed +++ b/tests/ui/manual_main_separator_str.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::manual_main_separator_str)] diff --git a/tests/ui/manual_main_separator_str.rs b/tests/ui/manual_main_separator_str.rs index 2dbb9e66151d..cf90e12efc33 100644 --- a/tests/ui/manual_main_separator_str.rs +++ b/tests/ui/manual_main_separator_str.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::manual_main_separator_str)] diff --git a/tests/ui/manual_map_option.fixed b/tests/ui/manual_map_option.fixed index e12ea7ec1450..e8ff65cad6aa 100644 --- a/tests/ui/manual_map_option.fixed +++ b/tests/ui/manual_map_option.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_map)] #![allow( diff --git a/tests/ui/manual_map_option.rs b/tests/ui/manual_map_option.rs index 325a6db06c4e..b06a96451ce7 100644 --- a/tests/ui/manual_map_option.rs +++ b/tests/ui/manual_map_option.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_map)] #![allow( diff --git a/tests/ui/manual_map_option.stderr b/tests/ui/manual_map_option.stderr index cdc2c0e62a9b..3f9caad4e89e 100644 --- a/tests/ui/manual_map_option.stderr +++ b/tests/ui/manual_map_option.stderr @@ -5,7 +5,7 @@ LL | / match Some(0) { LL | | Some(_) => Some(2), LL | | None:: => None, LL | | }; - | |_____^ help: try this: `Some(0).map(|_| 2)` + | |_____^ help: try: `Some(0).map(|_| 2)` | = note: `-D clippy::manual-map` implied by `-D warnings` @@ -16,7 +16,7 @@ LL | / match Some(0) { LL | | Some(x) => Some(x + 1), LL | | _ => None, LL | | }; - | |_____^ help: try this: `Some(0).map(|x| x + 1)` + | |_____^ help: try: `Some(0).map(|x| x + 1)` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:25:5 @@ -25,7 +25,7 @@ LL | / match Some("") { LL | | Some(x) => Some(x.is_empty()), LL | | None => None, LL | | }; - | |_____^ help: try this: `Some("").map(|x| x.is_empty())` + | |_____^ help: try: `Some("").map(|x| x.is_empty())` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:30:5 @@ -35,7 +35,7 @@ LL | | Some(!x) LL | | } else { LL | | None LL | | }; - | |_____^ help: try this: `Some(0).map(|x| !x)` + | |_____^ help: try: `Some(0).map(|x| !x)` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:37:5 @@ -44,7 +44,7 @@ LL | / match Some(0) { LL | | Some(x) => { Some(std::convert::identity(x)) } LL | | None => { None } LL | | }; - | |_____^ help: try this: `Some(0).map(std::convert::identity)` + | |_____^ help: try: `Some(0).map(std::convert::identity)` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:42:5 @@ -53,7 +53,7 @@ LL | / match Some(&String::new()) { LL | | Some(x) => Some(str::len(x)), LL | | None => None, LL | | }; - | |_____^ help: try this: `Some(&String::new()).map(|x| str::len(x))` + | |_____^ help: try: `Some(&String::new()).map(|x| str::len(x))` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:52:5 @@ -62,7 +62,7 @@ LL | / match &Some([0, 1]) { LL | | Some(x) => Some(x[0]), LL | | &None => None, LL | | }; - | |_____^ help: try this: `Some([0, 1]).as_ref().map(|x| x[0])` + | |_____^ help: try: `Some([0, 1]).as_ref().map(|x| x[0])` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:57:5 @@ -71,7 +71,7 @@ LL | / match &Some(0) { LL | | &Some(x) => Some(x * 2), LL | | None => None, LL | | }; - | |_____^ help: try this: `Some(0).map(|x| x * 2)` + | |_____^ help: try: `Some(0).map(|x| x * 2)` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:62:5 @@ -80,7 +80,7 @@ LL | / match Some(String::new()) { LL | | Some(ref x) => Some(x.is_empty()), LL | | _ => None, LL | | }; - | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())` + | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:67:5 @@ -89,7 +89,7 @@ LL | / match &&Some(String::new()) { LL | | Some(x) => Some(x.len()), LL | | _ => None, LL | | }; - | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())` + | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:72:5 @@ -98,7 +98,7 @@ LL | / match &&Some(0) { LL | | &&Some(x) => Some(x + x), LL | | &&_ => None, LL | | }; - | |_____^ help: try this: `Some(0).map(|x| x + x)` + | |_____^ help: try: `Some(0).map(|x| x + x)` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:85:9 @@ -107,7 +107,7 @@ LL | / match &mut Some(String::new()) { LL | | Some(x) => Some(x.push_str("")), LL | | None => None, LL | | }; - | |_________^ help: try this: `Some(String::new()).as_mut().map(|x| x.push_str(""))` + | |_________^ help: try: `Some(String::new()).as_mut().map(|x| x.push_str(""))` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:91:5 @@ -116,7 +116,7 @@ LL | / match &mut Some(String::new()) { LL | | Some(ref x) => Some(x.len()), LL | | None => None, LL | | }; - | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())` + | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:96:5 @@ -125,7 +125,7 @@ LL | / match &mut &Some(String::new()) { LL | | Some(x) => Some(x.is_empty()), LL | | &mut _ => None, LL | | }; - | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())` + | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:101:5 @@ -134,7 +134,7 @@ LL | / match Some((0, 1, 2)) { LL | | Some((x, y, z)) => Some(x + y + z), LL | | None => None, LL | | }; - | |_____^ help: try this: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)` + | |_____^ help: try: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:106:5 @@ -143,7 +143,7 @@ LL | / match Some([1, 2, 3]) { LL | | Some([first, ..]) => Some(first), LL | | None => None, LL | | }; - | |_____^ help: try this: `Some([1, 2, 3]).map(|[first, ..]| first)` + | |_____^ help: try: `Some([1, 2, 3]).map(|[first, ..]| first)` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:111:5 @@ -152,7 +152,7 @@ LL | / match &Some((String::new(), "test")) { LL | | Some((x, y)) => Some((y, x)), LL | | None => None, LL | | }; - | |_____^ help: try this: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))` + | |_____^ help: try: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:169:5 @@ -161,7 +161,7 @@ LL | / match Some(0) { LL | | Some(x) => Some(vec![x]), LL | | None => None, LL | | }; - | |_____^ help: try this: `Some(0).map(|x| vec![x])` + | |_____^ help: try: `Some(0).map(|x| vec![x])` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:174:5 @@ -170,7 +170,7 @@ LL | / match option_env!("") { LL | | Some(x) => Some(String::from(x)), LL | | None => None, LL | | }; - | |_____^ help: try this: `option_env!("").map(String::from)` + | |_____^ help: try: `option_env!("").map(String::from)` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:194:12 @@ -181,7 +181,7 @@ LL | | Some(x + 1) LL | | } else { LL | | None LL | | }; - | |_____^ help: try this: `{ Some(0).map(|x| x + 1) }` + | |_____^ help: try: `{ Some(0).map(|x| x + 1) }` error: manual implementation of `Option::map` --> $DIR/manual_map_option.rs:202:12 @@ -192,7 +192,7 @@ LL | | Some(x + 1) LL | | } else { LL | | None LL | | }; - | |_____^ help: try this: `{ Some(0).map(|x| x + 1) }` + | |_____^ help: try: `{ Some(0).map(|x| x + 1) }` error: aborting due to 21 previous errors diff --git a/tests/ui/manual_map_option_2.fixed b/tests/ui/manual_map_option_2.fixed index ebf3f8cabd47..dc7228782487 100644 --- a/tests/ui/manual_map_option_2.fixed +++ b/tests/ui/manual_map_option_2.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_map)] #![allow(clippy::toplevel_ref_arg)] diff --git a/tests/ui/manual_map_option_2.rs b/tests/ui/manual_map_option_2.rs index 1382d9af0aa0..c495ab0fa6e0 100644 --- a/tests/ui/manual_map_option_2.rs +++ b/tests/ui/manual_map_option_2.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_map)] #![allow(clippy::toplevel_ref_arg)] diff --git a/tests/ui/manual_map_option_2.stderr b/tests/ui/manual_map_option_2.stderr index d35b6252fb87..8c78fcffca8c 100644 --- a/tests/ui/manual_map_option_2.stderr +++ b/tests/ui/manual_map_option_2.stderr @@ -12,7 +12,7 @@ LL | | }; | |_____^ | = note: `-D clippy::manual-map` implied by `-D warnings` -help: try this +help: try | LL ~ let _ = Some(0).map(|x| { LL + let y = (String::new(), String::new()); @@ -32,7 +32,7 @@ LL | | None => None, LL | | }; | |_____^ | -help: try this +help: try | LL ~ let _ = s.as_ref().map(|x| { LL + if let Some(ref s) = s { (x.clone(), s) } else { panic!() } @@ -47,7 +47,7 @@ LL | let _ = match Some(0) { LL | | Some(x) => Some(f(x)), LL | | None => None, LL | | }; - | |_________^ help: try this: `Some(0).map(|x| f(x))` + | |_________^ help: try: `Some(0).map(|x| f(x))` error: manual implementation of `Option::map` --> $DIR/manual_map_option_2.rs:67:13 @@ -57,7 +57,7 @@ LL | let _ = match Some(0) { LL | | Some(x) => unsafe { Some(f(x)) }, LL | | None => None, LL | | }; - | |_____^ help: try this: `Some(0).map(|x| unsafe { f(x) })` + | |_____^ help: try: `Some(0).map(|x| unsafe { f(x) })` error: manual implementation of `Option::map` --> $DIR/manual_map_option_2.rs:71:13 @@ -67,7 +67,7 @@ LL | let _ = match Some(0) { LL | | Some(x) => Some(unsafe { f(x) }), LL | | None => None, LL | | }; - | |_____^ help: try this: `Some(0).map(|x| unsafe { f(x) })` + | |_____^ help: try: `Some(0).map(|x| unsafe { f(x) })` error: aborting due to 5 previous errors diff --git a/tests/ui/manual_memcpy/without_loop_counters.rs b/tests/ui/manual_memcpy/without_loop_counters.rs index ea0535d076b8..4d5c70f19a06 100644 --- a/tests/ui/manual_memcpy/without_loop_counters.rs +++ b/tests/ui/manual_memcpy/without_loop_counters.rs @@ -1,4 +1,5 @@ #![warn(clippy::needless_range_loop, clippy::manual_memcpy)] +#![allow(clippy::useless_vec)] const LOOP_OFFSET: usize = 5000; diff --git a/tests/ui/manual_memcpy/without_loop_counters.stderr b/tests/ui/manual_memcpy/without_loop_counters.stderr index c163ae061dfc..1c6a7d5c04e0 100644 --- a/tests/ui/manual_memcpy/without_loop_counters.stderr +++ b/tests/ui/manual_memcpy/without_loop_counters.stderr @@ -1,5 +1,5 @@ error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:7:5 + --> $DIR/without_loop_counters.rs:8:5 | LL | / for i in 0..src.len() { LL | | dst[i] = src[i]; @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::manual-memcpy` implied by `-D warnings` error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:12:5 + --> $DIR/without_loop_counters.rs:13:5 | LL | / for i in 0..src.len() { LL | | dst[i + 10] = src[i]; @@ -17,7 +17,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[10..(src.len() + 10)].copy_from_slice(&src[..]);` error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:17:5 + --> $DIR/without_loop_counters.rs:18:5 | LL | / for i in 0..src.len() { LL | | dst[i] = src[i + 10]; @@ -25,7 +25,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[10..(src.len() + 10)]);` error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:22:5 + --> $DIR/without_loop_counters.rs:23:5 | LL | / for i in 11..src.len() { LL | | dst[i] = src[i - 10]; @@ -33,7 +33,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[11..src.len()].copy_from_slice(&src[(11 - 10)..(src.len() - 10)]);` error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:27:5 + --> $DIR/without_loop_counters.rs:28:5 | LL | / for i in 0..dst.len() { LL | | dst[i] = src[i]; @@ -41,7 +41,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..dst.len()]);` error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:40:5 + --> $DIR/without_loop_counters.rs:41:5 | LL | / for i in 10..256 { LL | | dst[i] = src[i - 5]; @@ -56,7 +56,7 @@ LL + dst2[(10 + 500)..(256 + 500)].copy_from_slice(&src[10..256]); | error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:52:5 + --> $DIR/without_loop_counters.rs:53:5 | LL | / for i in 10..LOOP_OFFSET { LL | | dst[i + LOOP_OFFSET] = src[i - some_var]; @@ -64,7 +64,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].copy_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - some_var)]);` error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:65:5 + --> $DIR/without_loop_counters.rs:66:5 | LL | / for i in 0..src_vec.len() { LL | | dst_vec[i] = src_vec[i]; @@ -72,7 +72,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst_vec[..src_vec.len()].copy_from_slice(&src_vec[..]);` error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:94:5 + --> $DIR/without_loop_counters.rs:95:5 | LL | / for i in from..from + src.len() { LL | | dst[i] = src[i - from]; @@ -80,7 +80,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[from..(from + src.len())].copy_from_slice(&src[..(from + src.len() - from)]);` error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:98:5 + --> $DIR/without_loop_counters.rs:99:5 | LL | / for i in from..from + 3 { LL | | dst[i] = src[i - from]; @@ -88,7 +88,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[from..(from + 3)].copy_from_slice(&src[..(from + 3 - from)]);` error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:103:5 + --> $DIR/without_loop_counters.rs:104:5 | LL | / for i in 0..5 { LL | | dst[i - 0] = src[i]; @@ -96,7 +96,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src[..5]);` error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:108:5 + --> $DIR/without_loop_counters.rs:109:5 | LL | / for i in 0..0 { LL | | dst[i] = src[i]; @@ -104,7 +104,7 @@ LL | | } | |_____^ help: try replacing the loop by: `dst[..0].copy_from_slice(&src[..0]);` error: it looks like you're manually copying between slices - --> $DIR/without_loop_counters.rs:131:5 + --> $DIR/without_loop_counters.rs:132:5 | LL | / for i in 0..src.len() { LL | | dst[i] = src[i].clone(); diff --git a/tests/ui/manual_next_back.fixed b/tests/ui/manual_next_back.fixed new file mode 100644 index 000000000000..e8a47063ad61 --- /dev/null +++ b/tests/ui/manual_next_back.fixed @@ -0,0 +1,36 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::manual_next_back)] + +struct FakeIter(std::ops::Range); + +impl FakeIter { + fn rev(self) -> Self { + self + } + + fn next(&self) {} +} + +impl DoubleEndedIterator for FakeIter { + fn next_back(&mut self) -> Option { + self.0.next_back() + } +} + +impl Iterator for FakeIter { + type Item = i32; + fn next(&mut self) -> Option { + self.0.next() + } +} + +fn main() { + // should not lint + FakeIter(0..10).rev().next(); + + // should lint + let _ = (0..10).next_back().unwrap(); + let _ = "something".bytes().next_back(); +} diff --git a/tests/ui/manual_next_back.rs b/tests/ui/manual_next_back.rs new file mode 100644 index 000000000000..9ec89242241c --- /dev/null +++ b/tests/ui/manual_next_back.rs @@ -0,0 +1,36 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::manual_next_back)] + +struct FakeIter(std::ops::Range); + +impl FakeIter { + fn rev(self) -> Self { + self + } + + fn next(&self) {} +} + +impl DoubleEndedIterator for FakeIter { + fn next_back(&mut self) -> Option { + self.0.next_back() + } +} + +impl Iterator for FakeIter { + type Item = i32; + fn next(&mut self) -> Option { + self.0.next() + } +} + +fn main() { + // should not lint + FakeIter(0..10).rev().next(); + + // should lint + let _ = (0..10).rev().next().unwrap(); + let _ = "something".bytes().rev().next(); +} diff --git a/tests/ui/manual_next_back.stderr b/tests/ui/manual_next_back.stderr new file mode 100644 index 000000000000..94ccaa9e4cc3 --- /dev/null +++ b/tests/ui/manual_next_back.stderr @@ -0,0 +1,16 @@ +error: manual backwards iteration + --> $DIR/manual_next_back.rs:34:20 + | +LL | let _ = (0..10).rev().next().unwrap(); + | ^^^^^^^^^^^^^ help: use: `.next_back()` + | + = note: `-D clippy::manual-next-back` implied by `-D warnings` + +error: manual backwards iteration + --> $DIR/manual_next_back.rs:35:32 + | +LL | let _ = "something".bytes().rev().next(); + | ^^^^^^^^^^^^^ help: use: `.next_back()` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/manual_ok_or.fixed b/tests/ui/manual_ok_or.fixed index fc8511626b3d..d8901dc3b037 100644 --- a/tests/ui/manual_ok_or.fixed +++ b/tests/ui/manual_ok_or.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_ok_or)] #![allow(clippy::or_fun_call)] #![allow(clippy::disallowed_names)] diff --git a/tests/ui/manual_ok_or.rs b/tests/ui/manual_ok_or.rs index b5303d33f5fd..7188a521357e 100644 --- a/tests/ui/manual_ok_or.rs +++ b/tests/ui/manual_ok_or.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_ok_or)] #![allow(clippy::or_fun_call)] #![allow(clippy::disallowed_names)] diff --git a/tests/ui/manual_range_patterns.fixed b/tests/ui/manual_range_patterns.fixed new file mode 100644 index 000000000000..6bfcf263aa5e --- /dev/null +++ b/tests/ui/manual_range_patterns.fixed @@ -0,0 +1,39 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::manual_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + let f = 6; + + let _ = matches!(f, 1..=10); + let _ = matches!(f, 1..=10); + let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 8 | 10); // 7 is missing + let _ = matches!(f, | 4); + let _ = matches!(f, 4 | 5); + let _ = matches!(f, 1 | 2147483647); + let _ = matches!(f, 0 | 2147483647); + let _ = matches!(f, -2147483647 | 2147483647); + let _ = matches!(f, 1 | (2..=4)); + let _ = matches!(f, 1 | (2..4)); + let _ = matches!(f, 1..=48324729); + let _ = matches!(f, 0..=48324730); + let _ = matches!(f, 0..=3); + #[allow(clippy::match_like_matches_macro)] + let _ = match f { + 1..=10 => true, + _ => false, + }; + let _ = matches!(f, -5..=3); + let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1); // 2 is missing + let _ = matches!(f, -1000001..=1000001); + let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_002); + + macro_rules! mac { + ($e:expr) => { + matches!($e, 1..=10) + }; + } + mac!(f); +} diff --git a/tests/ui/manual_range_patterns.rs b/tests/ui/manual_range_patterns.rs new file mode 100644 index 000000000000..4a429bb2aed3 --- /dev/null +++ b/tests/ui/manual_range_patterns.rs @@ -0,0 +1,39 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::manual_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + let f = 6; + + let _ = matches!(f, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10); + let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 7 | 8 | 10); + let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 8 | 10); // 7 is missing + let _ = matches!(f, | 4); + let _ = matches!(f, 4 | 5); + let _ = matches!(f, 1 | 2147483647); + let _ = matches!(f, 0 | 2147483647); + let _ = matches!(f, -2147483647 | 2147483647); + let _ = matches!(f, 1 | (2..=4)); + let _ = matches!(f, 1 | (2..4)); + let _ = matches!(f, (1..=10) | (2..=13) | (14..=48324728) | 48324729); + let _ = matches!(f, 0 | (1..=10) | 48324730 | (2..=13) | (14..=48324728) | 48324729); + let _ = matches!(f, 0..=1 | 0..=2 | 0..=3); + #[allow(clippy::match_like_matches_macro)] + let _ = match f { + 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 => true, + _ => false, + }; + let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1 | 2); + let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1); // 2 is missing + let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_001); + let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_002); + + macro_rules! mac { + ($e:expr) => { + matches!($e, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10) + }; + } + mac!(f); +} diff --git a/tests/ui/manual_range_patterns.stderr b/tests/ui/manual_range_patterns.stderr new file mode 100644 index 000000000000..b1b55d483e72 --- /dev/null +++ b/tests/ui/manual_range_patterns.stderr @@ -0,0 +1,63 @@ +error: this OR pattern can be rewritten using a range + --> $DIR/manual_range_patterns.rs:10:25 + | +LL | let _ = matches!(f, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10` + | + = note: `-D clippy::manual-range-patterns` implied by `-D warnings` + +error: this OR pattern can be rewritten using a range + --> $DIR/manual_range_patterns.rs:11:25 + | +LL | let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 7 | 8 | 10); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10` + +error: this OR pattern can be rewritten using a range + --> $DIR/manual_range_patterns.rs:20:25 + | +LL | let _ = matches!(f, (1..=10) | (2..=13) | (14..=48324728) | 48324729); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=48324729` + +error: this OR pattern can be rewritten using a range + --> $DIR/manual_range_patterns.rs:21:25 + | +LL | let _ = matches!(f, 0 | (1..=10) | 48324730 | (2..=13) | (14..=48324728) | 48324729); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0..=48324730` + +error: this OR pattern can be rewritten using a range + --> $DIR/manual_range_patterns.rs:22:25 + | +LL | let _ = matches!(f, 0..=1 | 0..=2 | 0..=3); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `0..=3` + +error: this OR pattern can be rewritten using a range + --> $DIR/manual_range_patterns.rs:25:9 + | +LL | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 => true, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10` + +error: this OR pattern can be rewritten using a range + --> $DIR/manual_range_patterns.rs:28:25 + | +LL | let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1 | 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-5..=3` + +error: this OR pattern can be rewritten using a range + --> $DIR/manual_range_patterns.rs:30:25 + | +LL | let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_001); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-1000001..=1000001` + +error: this OR pattern can be rewritten using a range + --> $DIR/manual_range_patterns.rs:35:26 + | +LL | matches!($e, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10` +... +LL | mac!(f); + | ------- in this macro invocation + | + = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 9 previous errors + diff --git a/tests/ui/manual_rem_euclid.fixed b/tests/ui/manual_rem_euclid.fixed index 1f6df1b0a865..a3938ee95abb 100644 --- a/tests/ui/manual_rem_euclid.fixed +++ b/tests/ui/manual_rem_euclid.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::manual_rem_euclid)] #![allow(clippy::let_with_type_underscore)] diff --git a/tests/ui/manual_rem_euclid.rs b/tests/ui/manual_rem_euclid.rs index b275e8a38d21..4c7473434c45 100644 --- a/tests/ui/manual_rem_euclid.rs +++ b/tests/ui/manual_rem_euclid.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::manual_rem_euclid)] #![allow(clippy::let_with_type_underscore)] diff --git a/tests/ui/manual_retain.fixed b/tests/ui/manual_retain.fixed index 8f25fea678f1..c95d40fecba6 100644 --- a/tests/ui/manual_retain.fixed +++ b/tests/ui/manual_retain.fixed @@ -1,12 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_retain)] #![allow(unused, clippy::redundant_clone)] -use std::collections::BTreeMap; -use std::collections::BTreeSet; -use std::collections::BinaryHeap; -use std::collections::HashMap; -use std::collections::HashSet; -use std::collections::VecDeque; +use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque}; fn main() { binary_heap_retain(); @@ -23,8 +18,8 @@ fn main() { } fn binary_heap_retain() { - // NOTE: Do not lint now, because binary_heap_retain is nighyly API. - // And we need to add a test case for msrv if we update this implmention. + // NOTE: Do not lint now, because binary_heap_retain is nightly API. + // And we need to add a test case for msrv if we update this implementation. // https://github.com/rust-lang/rust/issues/71503 let mut heap = BinaryHeap::from([1, 2, 3]); heap = heap.into_iter().filter(|x| x % 2 == 0).collect(); diff --git a/tests/ui/manual_retain.rs b/tests/ui/manual_retain.rs index e6b3995a689b..9a3434f489de 100644 --- a/tests/ui/manual_retain.rs +++ b/tests/ui/manual_retain.rs @@ -1,12 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_retain)] #![allow(unused, clippy::redundant_clone)] -use std::collections::BTreeMap; -use std::collections::BTreeSet; -use std::collections::BinaryHeap; -use std::collections::HashMap; -use std::collections::HashSet; -use std::collections::VecDeque; +use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque}; fn main() { binary_heap_retain(); @@ -23,8 +18,8 @@ fn main() { } fn binary_heap_retain() { - // NOTE: Do not lint now, because binary_heap_retain is nighyly API. - // And we need to add a test case for msrv if we update this implmention. + // NOTE: Do not lint now, because binary_heap_retain is nightly API. + // And we need to add a test case for msrv if we update this implementation. // https://github.com/rust-lang/rust/issues/71503 let mut heap = BinaryHeap::from([1, 2, 3]); heap = heap.into_iter().filter(|x| x % 2 == 0).collect(); diff --git a/tests/ui/manual_retain.stderr b/tests/ui/manual_retain.stderr index 89316ce1d998..0936a23841ce 100644 --- a/tests/ui/manual_retain.stderr +++ b/tests/ui/manual_retain.stderr @@ -1,5 +1,5 @@ error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:51:5 + --> $DIR/manual_retain.rs:46:5 | LL | btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|k, _| k % 2 == 0)` @@ -7,13 +7,13 @@ LL | btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect() = note: `-D clippy::manual-retain` implied by `-D warnings` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:52:5 + --> $DIR/manual_retain.rs:47:5 | LL | btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|_, &mut v| v % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:53:5 + --> $DIR/manual_retain.rs:48:5 | LL | / btree_map = btree_map LL | | .into_iter() @@ -22,37 +22,37 @@ LL | | .collect(); | |__________________^ help: consider calling `.retain()` instead: `btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:75:5 + --> $DIR/manual_retain.rs:70:5 | LL | btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:76:5 + --> $DIR/manual_retain.rs:71:5 | LL | btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:77:5 + --> $DIR/manual_retain.rs:72:5 | LL | btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:107:5 + --> $DIR/manual_retain.rs:102:5 | LL | hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|k, _| k % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:108:5 + --> $DIR/manual_retain.rs:103:5 | LL | hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|_, &mut v| v % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:109:5 + --> $DIR/manual_retain.rs:104:5 | LL | / hash_map = hash_map LL | | .into_iter() @@ -61,61 +61,61 @@ LL | | .collect(); | |__________________^ help: consider calling `.retain()` instead: `hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:130:5 + --> $DIR/manual_retain.rs:125:5 | LL | hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:131:5 + --> $DIR/manual_retain.rs:126:5 | LL | hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:132:5 + --> $DIR/manual_retain.rs:127:5 | LL | hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:161:5 + --> $DIR/manual_retain.rs:156:5 | LL | s = s.chars().filter(|&c| c != 'o').to_owned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `s.retain(|c| c != 'o')` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:173:5 + --> $DIR/manual_retain.rs:168:5 | LL | vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:174:5 + --> $DIR/manual_retain.rs:169:5 | LL | vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:175:5 + --> $DIR/manual_retain.rs:170:5 | LL | vec = vec.into_iter().filter(|x| x % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:197:5 + --> $DIR/manual_retain.rs:192:5 | LL | vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:198:5 + --> $DIR/manual_retain.rs:193:5 | LL | vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)` error: this expression can be written more simply using `.retain()` - --> $DIR/manual_retain.rs:199:5 + --> $DIR/manual_retain.rs:194:5 | LL | vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)` diff --git a/tests/ui/manual_saturating_arithmetic.fixed b/tests/ui/manual_saturating_arithmetic.fixed index c4f53c446c9f..7dd4521fa78e 100644 --- a/tests/ui/manual_saturating_arithmetic.fixed +++ b/tests/ui/manual_saturating_arithmetic.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports)] diff --git a/tests/ui/manual_saturating_arithmetic.rs b/tests/ui/manual_saturating_arithmetic.rs index cd83cf6e65e9..463ee0692899 100644 --- a/tests/ui/manual_saturating_arithmetic.rs +++ b/tests/ui/manual_saturating_arithmetic.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports)] diff --git a/tests/ui/manual_slice_size_calculation.fixed b/tests/ui/manual_slice_size_calculation.fixed new file mode 100644 index 000000000000..11cb7de1886d --- /dev/null +++ b/tests/ui/manual_slice_size_calculation.fixed @@ -0,0 +1,185 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4da6e7e06 (rebase attempt) +//@run-rustfix +//@aux-build:proc_macros.rs:proc-macro +======= +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) +#![allow(unused)] +#![warn(clippy::manual_slice_size_calculation)] + +extern crate proc_macros; + +use core::mem::{align_of, size_of}; +use proc_macros::external; +<<<<<<< HEAD +======= +<<<<<<< HEAD +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +// run-rustfix +// aux-build:proc_macros.rs +======= +//@run-rustfix +//@aux-build:proc_macros.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +#![allow(unused)] +#![warn(clippy::manual_slice_size_calculation)] + +extern crate proc_macros; + +use core::mem::{align_of, size_of}; +<<<<<<< HEAD +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= +use proc_macros::external; +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +// run-rustfix +// aux-build:proc_macros.rs +======= +//@run-rustfix +//@aux-build:proc_macros.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +#![allow(unused)] +#![warn(clippy::manual_slice_size_calculation)] + +extern crate proc_macros; + +use core::mem::{align_of, size_of}; +<<<<<<< HEAD +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= +use proc_macros::external; +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + +fn main() { + let v_i32 = Vec::::new(); + let s_i32 = v_i32.as_slice(); + + // True positives: + let _ = std::mem::size_of_val(s_i32); // WARNING + let _ = std::mem::size_of_val(s_i32); // WARNING + let _ = std::mem::size_of_val(s_i32) * 5; // WARNING + + let len = s_i32.len(); + let size = size_of::(); + let _ = std::mem::size_of_val(s_i32); // WARNING + let _ = std::mem::size_of_val(s_i32); // WARNING + let _ = std::mem::size_of_val(s_i32); // WARNING + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + let _ = std::mem::size_of_val(external!(&[1u64][..])); + +======= +======= + let _ = std::mem::size_of_val(external!(&[1u64][..])); + +======= +<<<<<<< HEAD +<<<<<<< HEAD + let _ = std::mem::size_of_val(external!(&[1u64][..])); + +======= +>>>>>>> 4da6e7e06 (rebase attempt) +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= + let _ = std::mem::size_of_val(external!(&[1u64][..])); + +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +<<<<<<< HEAD +======= + let _ = std::mem::size_of_val(external!(&[1u64][..])); + +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= + let _ = std::mem::size_of_val(external!(&[1u64][..])); + +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + // True negatives: + let _ = size_of::() + s_i32.len(); // Ok, not a multiplication + let _ = size_of::() * s_i32.partition_point(|_| true); // Ok, not len() + let _ = size_of::() * v_i32.len(); // Ok, not a slice + let _ = align_of::() * s_i32.len(); // Ok, not size_of() + let _ = size_of::() * s_i32.len(); // Ok, different types + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) + let _ = external!($s_i32.len() * size_of::()); + let _ = external!($s_i32.len()) * size_of::(); + +======= +<<<<<<< HEAD +======= +<<<<<<< HEAD +<<<<<<< HEAD + let _ = external!($s_i32.len() * size_of::()); + let _ = external!($s_i32.len()) * size_of::(); + +======= +>>>>>>> 4da6e7e06 (rebase attempt) +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= + let _ = external!($s_i32.len() * size_of::()); + let _ = external!($s_i32.len()) * size_of::(); + +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +<<<<<<< HEAD +======= + let _ = external!($s_i32.len() * size_of::()); + let _ = external!($s_i32.len()) * size_of::(); + +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= + let _ = external!($s_i32.len() * size_of::()); + let _ = external!($s_i32.len()) * size_of::(); + +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + // False negatives: + let _ = 5 * size_of::() * s_i32.len(); // Ok (MISSED OPPORTUNITY) + let _ = size_of::() * 5 * s_i32.len(); // Ok (MISSED OPPORTUNITY) +} + +const fn _const(s_i32: &[i32]) { + // True negative: + let _ = s_i32.len() * size_of::(); // Ok, can't use size_of_val in const +} diff --git a/tests/ui/manual_slice_size_calculation.rs b/tests/ui/manual_slice_size_calculation.rs index 5082f931f3c2..7e60e3f5ec2d 100644 --- a/tests/ui/manual_slice_size_calculation.rs +++ b/tests/ui/manual_slice_size_calculation.rs @@ -1,7 +1,86 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 4da6e7e06 (rebase attempt) +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs +======= +// run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= +// aux-build:proc_macros.rs +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +======= +//@run-rustfix +//@aux-build:proc_macros.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +// run-rustfix +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= +// aux-build:proc_macros.rs +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +======= +//@run-rustfix +//@aux-build:proc_macros.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +//@aux-build:proc_macros.rs:proc-macro +<<<<<<< HEAD +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +//@aux-build:proc_macros.rs +======= +// run-rustfix +<<<<<<< HEAD +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= +// aux-build:proc_macros.rs +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +======= +//@run-rustfix +//@aux-build:proc_macros.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) #![allow(unused)] #![warn(clippy::manual_slice_size_calculation)] +extern crate proc_macros; + +use core::mem::{align_of, size_of}; +use proc_macros::external; +<<<<<<< HEAD +======= +======= +//@run-rustfix +//@aux-build:proc_macros.rs +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +#![allow(unused)] +#![warn(clippy::manual_slice_size_calculation)] + +extern crate proc_macros; + use core::mem::{align_of, size_of}; +<<<<<<< HEAD +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +use proc_macros::external; +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) fn main() { let v_i32 = Vec::::new(); @@ -18,6 +97,21 @@ fn main() { let _ = s_i32.len() * size; // WARNING let _ = len * size; // WARNING +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + let _ = external!(&[1u64][..]).len() * size_of::(); + +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + let _ = external!(&[1u64][..]).len() * size_of::(); + +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + let _ = external!(&[1u64][..]).len() * size_of::(); + +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) // True negatives: let _ = size_of::() + s_i32.len(); // Ok, not a multiplication let _ = size_of::() * s_i32.partition_point(|_| true); // Ok, not len() @@ -25,6 +119,24 @@ fn main() { let _ = align_of::() * s_i32.len(); // Ok, not size_of() let _ = size_of::() * s_i32.len(); // Ok, different types +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + let _ = external!($s_i32.len() * size_of::()); + let _ = external!($s_i32.len()) * size_of::(); + +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= + let _ = external!($s_i32.len() * size_of::()); + let _ = external!($s_i32.len()) * size_of::(); + +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + let _ = external!($s_i32.len() * size_of::()); + let _ = external!($s_i32.len()) * size_of::(); + +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) // False negatives: let _ = 5 * size_of::() * s_i32.len(); // Ok (MISSED OPPORTUNITY) let _ = size_of::() * 5 * s_i32.len(); // Ok (MISSED OPPORTUNITY) diff --git a/tests/ui/manual_slice_size_calculation.stderr b/tests/ui/manual_slice_size_calculation.stderr index 4a24fc60a0fa..e08067263fb0 100644 --- a/tests/ui/manual_slice_size_calculation.stderr +++ b/tests/ui/manual_slice_size_calculation.stderr @@ -1,51 +1,369 @@ error: manual slice size calculation - --> $DIR/manual_slice_size_calculation.rs:11:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_slice_size_calculation.rs:16:13 +======= +======= + --> $DIR/manual_slice_size_calculation.rs:16:13 +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_slice_size_calculation.rs:16:13 +======= +>>>>>>> 4da6e7e06 (rebase attempt) + --> $DIR/manual_slice_size_calculation.rs:12:13 +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= + --> $DIR/manual_slice_size_calculation.rs:16:13 +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +<<<<<<< HEAD +======= + --> $DIR/manual_slice_size_calculation.rs:12:13 +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= + --> $DIR/manual_slice_size_calculation.rs:16:13 +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +======= +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) | LL | let _ = s_i32.len() * size_of::(); // WARNING - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` | - = help: consider using std::mem::size_of_value instead +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD = note: `-D clippy::manual-slice-size-calculation` implied by `-D warnings` error: manual slice size calculation - --> $DIR/manual_slice_size_calculation.rs:12:13 +======= + = help: consider using std::mem::size_of_val instead +======= +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= +======= +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + = note: `-D clippy::manual-slice-size-calculation` implied by `-D warnings` + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:17:13 | LL | let _ = size_of::() * s_i32.len(); // WARNING - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +<<<<<<< HEAD +======= +======= + = help: consider using std::mem::size_of_val instead +======= +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) + = note: `-D clippy::manual-slice-size-calculation` implied by `-D warnings` + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:17:13 | - = help: consider using std::mem::size_of_value instead +LL | let _ = size_of::() * s_i32.len(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +>>>>>>> e4f5d83fa (Fixed formatting.) error: manual slice size calculation - --> $DIR/manual_slice_size_calculation.rs:13:13 + --> $DIR/manual_slice_size_calculation.rs:18:13 | LL | let _ = size_of::() * s_i32.len() * 5; // WARNING - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` + +error: manual slice size calculation +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) + --> $DIR/manual_slice_size_calculation.rs:17:13 +======= + --> $DIR/manual_slice_size_calculation.rs:18:13 +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) | - = help: consider using std::mem::size_of_value instead +LL | let _ = size_of::() * s_i32.len(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +======= + = help: consider using std::mem::size_of_val instead +======= +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) + = note: `-D clippy::manual-slice-size-calculation` implied by `-D warnings` error: manual slice size calculation --> $DIR/manual_slice_size_calculation.rs:17:13 | +LL | let _ = size_of::() * s_i32.len(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +======= + --> $DIR/manual_slice_size_calculation.rs:11:13 +======= + --> $DIR/manual_slice_size_calculation.rs:16:13 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) + | +LL | let _ = s_i32.len() * size_of::(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` + | + = note: `-D clippy::manual-slice-size-calculation` implied by `-D warnings` + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:17:13 + | +<<<<<<< HEAD LL | let _ = len * size_of::(); // WARNING +<<<<<<< HEAD | ^^^^^^^^^^^^^^^^^^^^^^ | +<<<<<<< HEAD = help: consider using std::mem::size_of_value instead +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +LL | let _ = size_of::() * s_i32.len(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + = help: consider using std::mem::size_of_val instead +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) +======= + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) error: manual slice size calculation --> $DIR/manual_slice_size_calculation.rs:18:13 | +<<<<<<< HEAD +<<<<<<< HEAD +LL | let _ = size_of::() * s_i32.len() * 5; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:22:13 + | +LL | let _ = len * size_of::(); // WARNING +<<<<<<< HEAD + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider using std::mem::size_of_val instead +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) +======= + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:23:13 + | +<<<<<<< HEAD +LL | let _ = size_of::() * s_i32.len() * 5; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +======= LL | let _ = s_i32.len() * size; // WARNING +<<<<<<< HEAD +<<<<<<< HEAD | ^^^^^^^^^^^^^^^^^^ | - = help: consider using std::mem::size_of_value instead + = help: consider using std::mem::size_of_val instead +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) +======= + | ^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= + | ^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) error: manual slice size calculation +======= +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) + --> $DIR/manual_slice_size_calculation.rs:22:13 + | +LL | let _ = len * size_of::(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` + +error: manual slice size calculation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_slice_size_calculation.rs:23:13 +======= --> $DIR/manual_slice_size_calculation.rs:19:13 +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= + --> $DIR/manual_slice_size_calculation.rs:23:13 +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) + | +LL | let _ = s_i32.len() * size; // WARNING + | ^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` + +error: manual slice size calculation +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_slice_size_calculation.rs:24:13 +======= + --> $DIR/manual_slice_size_calculation.rs:20:13 +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= + --> $DIR/manual_slice_size_calculation.rs:24:13 +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) | LL | let _ = len * size; // WARNING - | ^^^^^^^^^^ + | ^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +<<<<<<< HEAD +<<<<<<< HEAD + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:26:13 | +<<<<<<< HEAD +<<<<<<< HEAD +LL | let _ = external!(&[1u64][..]).len() * size_of::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))` +======= + = help: consider using std::mem::size_of_val instead +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) +======= +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= +LL | let _ = external!(&[1u64][..]).len() * size_of::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))` +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +======= +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) + +error: aborting due to 7 previous errors +======= +LL | let _ = s_i32.len() * size; // WARNING + | ^^^^^^^^^^^^^^^^^^ + | +<<<<<<< HEAD = help: consider using std::mem::size_of_value instead +======= +LL | let _ = size_of::() * s_i32.len() * 5; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + = help: consider using std::mem::size_of_val instead +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:22:13 + | +LL | let _ = len * size_of::(); // WARNING +<<<<<<< HEAD +======= +<<<<<<< HEAD + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider using std::mem::size_of_val instead +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) +======= + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:23:13 + | +<<<<<<< HEAD +LL | let _ = size_of::() * s_i32.len() * 5; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +======= +LL | let _ = s_i32.len() * size; // WARNING +<<<<<<< HEAD + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider using std::mem::size_of_val instead +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) +======= + | ^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:22:13 + | +LL | let _ = len * size_of::(); // WARNING +>>>>>>> e4f5d83fa (Fixed formatting.) + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:23:13 + | +LL | let _ = s_i32.len() * size; // WARNING + | ^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` + +error: manual slice size calculation +<<<<<<< HEAD + --> $DIR/manual_slice_size_calculation.rs:24:13 +======= + --> $DIR/manual_slice_size_calculation.rs:20:13 +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= + --> $DIR/manual_slice_size_calculation.rs:24:13 +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) + | +LL | let _ = len * size; // WARNING + | ^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +======= +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/manual_slice_size_calculation.rs:24:13 +======= + --> $DIR/manual_slice_size_calculation.rs:20:13 +>>>>>>> b8fee8b50 (Add run-rustfix marker and test file) +======= + --> $DIR/manual_slice_size_calculation.rs:24:13 +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) + | +LL | let _ = len * size; // WARNING + | ^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` +<<<<<<< HEAD +>>>>>>> e4f5d83fa (Fixed formatting.) + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:26:13 + | +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +LL | let _ = external!(&[1u64][..]).len() * size_of::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))` +======= + = help: consider using std::mem::size_of_val instead +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) + +<<<<<<< HEAD error: aborting due to 6 previous errors +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +error: aborting due to 7 previous errors +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +======= +>>>>>>> 4da6e7e06 (rebase attempt) +LL | let _ = external!(&[1u64][..]).len() * size_of::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))` +======= +<<<<<<< HEAD +<<<<<<< HEAD +LL | let _ = external!(&[1u64][..]).len() * size_of::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))` +======= + = help: consider using std::mem::size_of_val instead +>>>>>>> 4fb38cfb2 (Rename std::mem::size_of_value to std::mem::size_of_val) +======= +>>>>>>> 503fd56a4 (Suggest applicable expression for manual slice size calculation lint) +======= +LL | let _ = external!(&[1u64][..]).len() * size_of::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))` +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) +>>>>>>> e4f5d83fa (Fixed formatting.) + +error: aborting due to 7 previous errors +>>>>>>> 2f4f798f9 (Ignore `manual_slice_size_calculation` in code from macro expansions) diff --git a/tests/ui/manual_split_once.fixed b/tests/ui/manual_split_once.fixed index 50b02019cc27..e317c597109b 100644 --- a/tests/ui/manual_split_once.fixed +++ b/tests/ui/manual_split_once.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_split_once)] #![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)] diff --git a/tests/ui/manual_split_once.rs b/tests/ui/manual_split_once.rs index e1e8b71a9def..7e2dc22bc466 100644 --- a/tests/ui/manual_split_once.rs +++ b/tests/ui/manual_split_once.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_split_once)] #![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)] diff --git a/tests/ui/manual_split_once.stderr b/tests/ui/manual_split_once.stderr index 78da5a16cc52..f454f95b41dc 100644 --- a/tests/ui/manual_split_once.stderr +++ b/tests/ui/manual_split_once.stderr @@ -2,7 +2,7 @@ error: manual implementation of `split_once` --> $DIR/manual_split_once.rs:13:13 | LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').unwrap().1` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1` | = note: `-D clippy::manual-split-once` implied by `-D warnings` @@ -10,73 +10,73 @@ error: manual implementation of `split_once` --> $DIR/manual_split_once.rs:14:13 | LL | let _ = "key=value".splitn(2, '=').skip(1).next().unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').unwrap().1` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1` error: manual implementation of `split_once` --> $DIR/manual_split_once.rs:15:18 | LL | let (_, _) = "key=value".splitn(2, '=').next_tuple().unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=')` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=')` error: manual implementation of `split_once` --> $DIR/manual_split_once.rs:18:13 | LL | let _ = s.splitn(2, '=').nth(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').unwrap().1` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1` error: manual implementation of `split_once` --> $DIR/manual_split_once.rs:21:13 | LL | let _ = s.splitn(2, '=').nth(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').unwrap().1` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1` error: manual implementation of `split_once` --> $DIR/manual_split_once.rs:24:13 | LL | let _ = s.splitn(2, '=').skip(1).next().unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').unwrap().1` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1` error: manual implementation of `split_once` --> $DIR/manual_split_once.rs:27:17 | LL | let _ = s.splitn(2, '=').nth(1)?; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=')?.1` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1` error: manual implementation of `split_once` --> $DIR/manual_split_once.rs:28:17 | LL | let _ = s.splitn(2, '=').skip(1).next()?; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=')?.1` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1` error: manual implementation of `rsplit_once` --> $DIR/manual_split_once.rs:29:17 | LL | let _ = s.rsplitn(2, '=').nth(1)?; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit_once('=')?.0` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0` error: manual implementation of `rsplit_once` --> $DIR/manual_split_once.rs:30:17 | LL | let _ = s.rsplitn(2, '=').skip(1).next()?; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit_once('=')?.0` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0` error: manual implementation of `rsplit_once` --> $DIR/manual_split_once.rs:38:13 | LL | let _ = "key=value".rsplitn(2, '=').nth(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".rsplit_once('=').unwrap().0` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').unwrap().0` error: manual implementation of `rsplit_once` --> $DIR/manual_split_once.rs:39:18 | LL | let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".rsplit_once('=').map(|(x, y)| (y, x))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').map(|(x, y)| (y, x))` error: manual implementation of `rsplit_once` --> $DIR/manual_split_once.rs:40:13 | LL | let _ = s.rsplitn(2, '=').nth(1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit_once('=').map(|x| x.0)` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=').map(|x| x.0)` error: manual implementation of `split_once` --> $DIR/manual_split_once.rs:44:5 @@ -182,7 +182,7 @@ error: manual implementation of `split_once` --> $DIR/manual_split_once.rs:141:13 | LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').unwrap().1` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1` error: manual implementation of `split_once` --> $DIR/manual_split_once.rs:143:5 diff --git a/tests/ui/manual_str_repeat.fixed b/tests/ui/manual_str_repeat.fixed index 3d56f2a0dedb..9468c3df9047 100644 --- a/tests/ui/manual_str_repeat.fixed +++ b/tests/ui/manual_str_repeat.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_str_repeat)] diff --git a/tests/ui/manual_str_repeat.rs b/tests/ui/manual_str_repeat.rs index e8240a949dbc..baa0a10260d4 100644 --- a/tests/ui/manual_str_repeat.rs +++ b/tests/ui/manual_str_repeat.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_str_repeat)] diff --git a/tests/ui/manual_str_repeat.stderr b/tests/ui/manual_str_repeat.stderr index bdfee7cab261..331bb6ea575b 100644 --- a/tests/ui/manual_str_repeat.stderr +++ b/tests/ui/manual_str_repeat.stderr @@ -2,7 +2,7 @@ error: manual implementation of `str::repeat` using iterators --> $DIR/manual_str_repeat.rs:9:21 | LL | let _: String = std::iter::repeat("test").take(10).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"test".repeat(10)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"test".repeat(10)` | = note: `-D clippy::manual-str-repeat` implied by `-D warnings` @@ -10,55 +10,55 @@ error: manual implementation of `str::repeat` using iterators --> $DIR/manual_str_repeat.rs:10:21 | LL | let _: String = std::iter::repeat('x').take(10).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"x".repeat(10)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"x".repeat(10)` error: manual implementation of `str::repeat` using iterators --> $DIR/manual_str_repeat.rs:11:21 | LL | let _: String = std::iter::repeat('/'').take(10).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"'".repeat(10)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"'".repeat(10)` error: manual implementation of `str::repeat` using iterators --> $DIR/manual_str_repeat.rs:12:21 | LL | let _: String = std::iter::repeat('"').take(10).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"/"".repeat(10)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"/"".repeat(10)` error: manual implementation of `str::repeat` using iterators --> $DIR/manual_str_repeat.rs:16:13 | LL | let _ = repeat(x).take(count + 2).collect::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `x.repeat(count + 2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count + 2)` error: manual implementation of `str::repeat` using iterators --> $DIR/manual_str_repeat.rs:25:21 | LL | let _: String = repeat(*x).take(count).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `(*x).repeat(count)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*x).repeat(count)` error: manual implementation of `str::repeat` using iterators --> $DIR/manual_str_repeat.rs:34:21 | LL | let _: String = repeat(x).take(count).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `x.repeat(count)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count)` error: manual implementation of `str::repeat` using iterators --> $DIR/manual_str_repeat.rs:46:21 | LL | let _: String = repeat(Cow::Borrowed("test")).take(count).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Cow::Borrowed("test").repeat(count)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Cow::Borrowed("test").repeat(count)` error: manual implementation of `str::repeat` using iterators --> $DIR/manual_str_repeat.rs:49:21 | LL | let _: String = repeat(x).take(count).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `x.repeat(count)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count)` error: manual implementation of `str::repeat` using iterators --> $DIR/manual_str_repeat.rs:64:21 | LL | let _: String = std::iter::repeat("test").take(10).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"test".repeat(10)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"test".repeat(10)` error: aborting due to 10 previous errors diff --git a/tests/ui/manual_string_new.fixed b/tests/ui/manual_string_new.fixed index a376411bfbc8..0d1bab233046 100644 --- a/tests/ui/manual_string_new.fixed +++ b/tests/ui/manual_string_new.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_string_new)] diff --git a/tests/ui/manual_string_new.rs b/tests/ui/manual_string_new.rs index 6bfc52fb1bce..2392ebfc3229 100644 --- a/tests/ui/manual_string_new.rs +++ b/tests/ui/manual_string_new.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_string_new)] diff --git a/tests/ui/manual_try_fold.rs b/tests/ui/manual_try_fold.rs new file mode 100644 index 000000000000..8d342f919ad5 --- /dev/null +++ b/tests/ui/manual_try_fold.rs @@ -0,0 +1,115 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> 354172a18 (New lint `manual_try_fold`) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> fbb3f759e (update docs) +#![allow(clippy::unnecessary_fold, unused)] +#![warn(clippy::manual_try_fold)] +#![feature(try_trait_v2)] + +use std::ops::{ControlFlow, FromResidual, Try}; + +#[macro_use] +extern crate proc_macros; + +// Test custom `Try` with more than 1 argument +struct NotOption(i32, i32); + +impl FromResidual for NotOption { + fn from_residual(_: R) -> Self { + todo!() + } +} + +impl Try for NotOption { + type Output = (); + type Residual = (); + + fn from_output(_: Self::Output) -> Self { + todo!() + } + + fn branch(self) -> ControlFlow { + todo!() + } +} + +// Test custom `Try` with only 1 argument +#[derive(Default)] +struct NotOptionButWorse(i32); + +impl FromResidual for NotOptionButWorse { + fn from_residual(_: R) -> Self { + todo!() + } +} + +impl Try for NotOptionButWorse { + type Output = (); + type Residual = (); + + fn from_output(_: Self::Output) -> Self { + todo!() + } + + fn branch(self) -> ControlFlow { + todo!() + } +} + +fn main() { + [1, 2, 3] + .iter() + .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) + .unwrap(); + [1, 2, 3] + .iter() + .fold(NotOption(0i32, 0i32), |sum, i| NotOption(0i32, 0i32)); + [1, 2, 3] + .iter() + .fold(NotOptionButWorse(0i32), |sum, i| NotOptionButWorse(0i32)); + // Do not lint + [1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i)).unwrap(); + [1, 2, 3].iter().fold(0i32, |sum, i| sum + i); + [1, 2, 3] + .iter() + .fold(NotOptionButWorse::default(), |sum, i| NotOptionButWorse::default()); + external! { + [1, 2, 3].iter().fold(Some(0i32), |sum, i| sum?.checked_add(*i)).unwrap(); + [1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i)).unwrap(); + } + with_span! { + span + [1, 2, 3].iter().fold(Some(0i32), |sum, i| sum?.checked_add(*i)).unwrap(); + [1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i)).unwrap(); + } +} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 24039ca2c (Add msrv tests) + +#[clippy::msrv = "1.26.0"] +fn msrv_too_low() { + [1, 2, 3] + .iter() + .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) + .unwrap(); +} + +#[clippy::msrv = "1.27.0"] +fn msrv_juust_right() { + [1, 2, 3] + .iter() + .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) + .unwrap(); +} +<<<<<<< HEAD +======= +>>>>>>> 354172a18 (New lint `manual_try_fold`) +======= +>>>>>>> 24039ca2c (Add msrv tests) diff --git a/tests/ui/manual_try_fold.stderr b/tests/ui/manual_try_fold.stderr new file mode 100644 index 000000000000..b7215e0ae483 --- /dev/null +++ b/tests/ui/manual_try_fold.stderr @@ -0,0 +1,70 @@ +<<<<<<< HEAD +<<<<<<< HEAD +error: usage of `Iterator::fold` on a type that implements `Try` + --> $DIR/manual_try_fold.rs:59:10 + | +LL | .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)` + | + = note: `-D clippy::manual-try-fold` implied by `-D warnings` + +error: usage of `Iterator::fold` on a type that implements `Try` + --> $DIR/manual_try_fold.rs:63:10 + | +LL | .fold(NotOption(0i32, 0i32), |sum, i| NotOption(0i32, 0i32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(..., |sum, i| ...)` + +error: usage of `Iterator::fold` on a type that implements `Try` + --> $DIR/manual_try_fold.rs:66:10 + | +LL | .fold(NotOptionButWorse(0i32), |sum, i| NotOptionButWorse(0i32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)` + +error: usage of `Iterator::fold` on a type that implements `Try` + --> $DIR/manual_try_fold.rs:96:10 + | +LL | .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)` + +error: aborting due to 4 previous errors +======= +error: you seem to be using `Iterator::fold` on a type that implements `Try` +======= +error: usage of `Iterator::fold` on a type that implements `Try` +>>>>>>> cb5d7e344 (address comments) + --> $DIR/manual_try_fold.rs:61:10 + | +LL | .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)` + | + = note: `-D clippy::manual-try-fold` implied by `-D warnings` + +error: usage of `Iterator::fold` on a type that implements `Try` + --> $DIR/manual_try_fold.rs:65:10 + | +LL | .fold(NotOption(0i32, 0i32), |sum, i| NotOption(0i32, 0i32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(..., |sum, i| ...)` + +error: usage of `Iterator::fold` on a type that implements `Try` + --> $DIR/manual_try_fold.rs:68:10 + | +LL | .fold(NotOptionButWorse(0i32), |sum, i| NotOptionButWorse(0i32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)` + +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 3 previous errors +>>>>>>> 354172a18 (New lint `manual_try_fold`) +======= +error: you seem to be using `Iterator::fold` on a type that implements `Try` +======= +error: usage of `Iterator::fold` on a type that implements `Try` +>>>>>>> cb5d7e344 (address comments) + --> $DIR/manual_try_fold.rs:98:10 + | +LL | .fold(Some(0i32), |sum, i| sum?.checked_add(*i)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)` + +error: aborting due to 4 previous errors +>>>>>>> 24039ca2c (Add msrv tests) + diff --git a/tests/ui/manual_unwrap_or.fixed b/tests/ui/manual_unwrap_or.fixed index 7d68978216c9..20560b87c1a5 100644 --- a/tests/ui/manual_unwrap_or.fixed +++ b/tests/ui/manual_unwrap_or.fixed @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] -#![allow(unused_variables, clippy::unnecessary_wraps)] +#![allow(unused_variables, clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)] fn option_unwrap_or() { // int case diff --git a/tests/ui/manual_unwrap_or.rs b/tests/ui/manual_unwrap_or.rs index b937fe6f977e..5dbc57565bff 100644 --- a/tests/ui/manual_unwrap_or.rs +++ b/tests/ui/manual_unwrap_or.rs @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] -#![allow(unused_variables, clippy::unnecessary_wraps)] +#![allow(unused_variables, clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)] fn option_unwrap_or() { // int case diff --git a/tests/ui/manual_while_let_some.fixed b/tests/ui/manual_while_let_some.fixed new file mode 100644 index 000000000000..555e4e06dc0f --- /dev/null +++ b/tests/ui/manual_while_let_some.fixed @@ -0,0 +1,101 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= +// run-rustfix +>>>>>>> 8d8178f93 (rename lint to `manual_while_let_some`) +======= +//@run-rustfix +>>>>>>> 9613ea85c (fix run-rustfix directive) + +#![allow(unused)] +#![warn(clippy::manual_while_let_some)] + +struct VecInStruct { + numbers: Vec, + unrelated: String, +} + +struct Foo { + a: i32, + b: i32, +} + +fn accept_i32(_: i32) {} +fn accept_optional_i32(_: Option) {} +fn accept_i32_tuple(_: (i32, i32)) {} + +fn main() { + let mut numbers = vec![1, 2, 3, 4, 5]; + while let Some(number) = numbers.pop() { + + } + + let mut val = VecInStruct { + numbers: vec![1, 2, 3, 4, 5], + unrelated: String::new(), + }; + while let Some(number) = val.numbers.pop() { + + } + + while let Some(element) = numbers.pop() { + accept_i32(element); + } + + while let Some(element) = numbers.pop() { + accept_i32(element); + } + + // This should not warn. It "conditionally" pops elements. + while !numbers.is_empty() { + if true { + accept_i32(numbers.pop().unwrap()); + } + } + + // This should also not warn. It conditionally pops elements. + while !numbers.is_empty() { + if false { + continue; + } + accept_i32(numbers.pop().unwrap()); + } + + // This should not warn. It pops elements, but does not unwrap it. + // Might handle the Option in some other arbitrary way. + while !numbers.is_empty() { + accept_optional_i32(numbers.pop()); + } + + let unrelated_vec: Vec = Vec::new(); + // This should not warn. It pops elements from a different vector. + while !unrelated_vec.is_empty() { + accept_i32(numbers.pop().unwrap()); + } + + macro_rules! generate_loop { + () => { + while !numbers.is_empty() { + accept_i32(numbers.pop().unwrap()); + } + }; + } + // Do not warn if the loop comes from a macro. + generate_loop!(); + + // Try other kinds of patterns + let mut numbers = vec![(0, 0), (1, 1), (2, 2)]; + while let Some((a, b)) = numbers.pop() { + + } + + while let Some(element) = numbers.pop() { + accept_i32_tuple(element); + } + + let mut results = vec![Foo { a: 1, b: 2 }, Foo { a: 3, b: 4 }]; + while let Some(Foo { a, b }) = results.pop() { + + } +} diff --git a/tests/ui/manual_while_let_some.rs b/tests/ui/manual_while_let_some.rs new file mode 100644 index 000000000000..8663e6dae5f1 --- /dev/null +++ b/tests/ui/manual_while_let_some.rs @@ -0,0 +1,101 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= +// run-rustfix +>>>>>>> 8d8178f93 (rename lint to `manual_while_let_some`) +======= +//@run-rustfix +>>>>>>> 9613ea85c (fix run-rustfix directive) + +#![allow(unused)] +#![warn(clippy::manual_while_let_some)] + +struct VecInStruct { + numbers: Vec, + unrelated: String, +} + +struct Foo { + a: i32, + b: i32, +} + +fn accept_i32(_: i32) {} +fn accept_optional_i32(_: Option) {} +fn accept_i32_tuple(_: (i32, i32)) {} + +fn main() { + let mut numbers = vec![1, 2, 3, 4, 5]; + while !numbers.is_empty() { + let number = numbers.pop().unwrap(); + } + + let mut val = VecInStruct { + numbers: vec![1, 2, 3, 4, 5], + unrelated: String::new(), + }; + while !val.numbers.is_empty() { + let number = val.numbers.pop().unwrap(); + } + + while !numbers.is_empty() { + accept_i32(numbers.pop().unwrap()); + } + + while !numbers.is_empty() { + accept_i32(numbers.pop().expect("")); + } + + // This should not warn. It "conditionally" pops elements. + while !numbers.is_empty() { + if true { + accept_i32(numbers.pop().unwrap()); + } + } + + // This should also not warn. It conditionally pops elements. + while !numbers.is_empty() { + if false { + continue; + } + accept_i32(numbers.pop().unwrap()); + } + + // This should not warn. It pops elements, but does not unwrap it. + // Might handle the Option in some other arbitrary way. + while !numbers.is_empty() { + accept_optional_i32(numbers.pop()); + } + + let unrelated_vec: Vec = Vec::new(); + // This should not warn. It pops elements from a different vector. + while !unrelated_vec.is_empty() { + accept_i32(numbers.pop().unwrap()); + } + + macro_rules! generate_loop { + () => { + while !numbers.is_empty() { + accept_i32(numbers.pop().unwrap()); + } + }; + } + // Do not warn if the loop comes from a macro. + generate_loop!(); + + // Try other kinds of patterns + let mut numbers = vec![(0, 0), (1, 1), (2, 2)]; + while !numbers.is_empty() { + let (a, b) = numbers.pop().unwrap(); + } + + while !numbers.is_empty() { + accept_i32_tuple(numbers.pop().unwrap()); + } + + let mut results = vec![Foo { a: 1, b: 2 }, Foo { a: 3, b: 4 }]; + while !results.is_empty() { + let Foo { a, b } = results.pop().unwrap(); + } +} diff --git a/tests/ui/manual_while_let_some.stderr b/tests/ui/manual_while_let_some.stderr new file mode 100644 index 000000000000..633fe05c49b8 --- /dev/null +++ b/tests/ui/manual_while_let_some.stderr @@ -0,0 +1,87 @@ +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:23:9 + | +LL | let number = numbers.pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::manual-while-let-some` implied by `-D warnings` +help: consider using a `while..let` loop + | +LL ~ while let Some(number) = numbers.pop() { +LL ~ + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:31:9 + | +LL | let number = val.numbers.pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some(number) = val.numbers.pop() { +LL ~ + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:35:20 + | +LL | accept_i32(numbers.pop().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some(element) = numbers.pop() { +LL ~ accept_i32(element); + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:39:20 + | +LL | accept_i32(numbers.pop().expect("")); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some(element) = numbers.pop() { +LL ~ accept_i32(element); + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:82:9 + | +LL | let (a, b) = numbers.pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some((a, b)) = numbers.pop() { +LL ~ + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:86:26 + | +LL | accept_i32_tuple(numbers.pop().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some(element) = numbers.pop() { +LL ~ accept_i32_tuple(element); + | + +error: you seem to be trying to pop elements from a `Vec` in a loop + --> $DIR/manual_while_let_some.rs:91:9 + | +LL | let Foo { a, b } = results.pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a `while..let` loop + | +LL ~ while let Some(Foo { a, b }) = results.pop() { +LL ~ + | + +error: aborting due to 7 previous errors + diff --git a/tests/ui/map_clone.fixed b/tests/ui/map_clone.fixed index 0860dcf8e0dd..50c0eb1a8108 100644 --- a/tests/ui/map_clone.fixed +++ b/tests/ui/map_clone.fixed @@ -1,10 +1,11 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_clone)] #![allow( clippy::clone_on_copy, clippy::iter_cloned_collect, clippy::many_single_char_names, - clippy::redundant_clone + clippy::redundant_clone, + clippy::useless_vec )] fn main() { diff --git a/tests/ui/map_clone.rs b/tests/ui/map_clone.rs index b6987336834b..91a084f2844d 100644 --- a/tests/ui/map_clone.rs +++ b/tests/ui/map_clone.rs @@ -1,10 +1,11 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_clone)] #![allow( clippy::clone_on_copy, clippy::iter_cloned_collect, clippy::many_single_char_names, - clippy::redundant_clone + clippy::redundant_clone, + clippy::useless_vec )] fn main() { diff --git a/tests/ui/map_clone.stderr b/tests/ui/map_clone.stderr index d84a5bf8d4de..d768af1f48c9 100644 --- a/tests/ui/map_clone.stderr +++ b/tests/ui/map_clone.stderr @@ -1,5 +1,5 @@ error: you are using an explicit closure for copying elements - --> $DIR/map_clone.rs:11:22 + --> $DIR/map_clone.rs:12:22 | LL | let _: Vec = vec![5_i8; 6].iter().map(|x| *x).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `vec![5_i8; 6].iter().copied()` @@ -7,31 +7,31 @@ LL | let _: Vec = vec![5_i8; 6].iter().map(|x| *x).collect(); = note: `-D clippy::map-clone` implied by `-D warnings` error: you are using an explicit closure for cloning elements - --> $DIR/map_clone.rs:12:26 + --> $DIR/map_clone.rs:13:26 | LL | let _: Vec = vec![String::new()].iter().map(|x| x.clone()).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `vec![String::new()].iter().cloned()` error: you are using an explicit closure for copying elements - --> $DIR/map_clone.rs:13:23 + --> $DIR/map_clone.rs:14:23 | LL | let _: Vec = vec![42, 43].iter().map(|&x| x).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `vec![42, 43].iter().copied()` error: you are using an explicit closure for copying elements - --> $DIR/map_clone.rs:15:26 + --> $DIR/map_clone.rs:16:26 | LL | let _: Option = Some(&16).map(|b| *b); | ^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `Some(&16).copied()` error: you are using an explicit closure for copying elements - --> $DIR/map_clone.rs:16:25 + --> $DIR/map_clone.rs:17:25 | LL | let _: Option = Some(&1).map(|x| x.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `Some(&1).copied()` error: you are needlessly cloning iterator elements - --> $DIR/map_clone.rs:27:29 + --> $DIR/map_clone.rs:28:29 | LL | let _ = std::env::args().map(|v| v.clone()); | ^^^^^^^^^^^^^^^^^^^ help: remove the `map` call diff --git a/tests/ui/map_collect_result_unit.fixed b/tests/ui/map_collect_result_unit.fixed index e66c9cc24207..b00c2cf284ec 100644 --- a/tests/ui/map_collect_result_unit.fixed +++ b/tests/ui/map_collect_result_unit.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_collect_result_unit)] fn main() { diff --git a/tests/ui/map_collect_result_unit.rs b/tests/ui/map_collect_result_unit.rs index 6f08f4c3c535..ad2198ec1fe7 100644 --- a/tests/ui/map_collect_result_unit.rs +++ b/tests/ui/map_collect_result_unit.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_collect_result_unit)] fn main() { diff --git a/tests/ui/map_collect_result_unit.stderr b/tests/ui/map_collect_result_unit.stderr index 8b06e13baa6b..596e51e5741e 100644 --- a/tests/ui/map_collect_result_unit.stderr +++ b/tests/ui/map_collect_result_unit.stderr @@ -2,7 +2,7 @@ error: `.map().collect()` can be replaced with `.try_for_each()` --> $DIR/map_collect_result_unit.rs:6:17 | LL | let _ = (0..3).map(|t| Err(t + 1)).collect::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `(0..3).try_for_each(|t| Err(t + 1))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(0..3).try_for_each(|t| Err(t + 1))` | = note: `-D clippy::map-collect-result-unit` implied by `-D warnings` @@ -10,7 +10,7 @@ error: `.map().collect()` can be replaced with `.try_for_each()` --> $DIR/map_collect_result_unit.rs:7:32 | LL | let _: Result<(), _> = (0..3).map(|t| Err(t + 1)).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `(0..3).try_for_each(|t| Err(t + 1))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(0..3).try_for_each(|t| Err(t + 1))` error: aborting due to 2 previous errors diff --git a/tests/ui/map_flatten_fixable.fixed b/tests/ui/map_flatten_fixable.fixed index 8e2f11389f89..14816de1a636 100644 --- a/tests/ui/map_flatten_fixable.fixed +++ b/tests/ui/map_flatten_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::pedantic)] #![allow(clippy::let_underscore_untyped)] diff --git a/tests/ui/map_flatten_fixable.rs b/tests/ui/map_flatten_fixable.rs index a783a99c4ffd..f38a00a59fac 100644 --- a/tests/ui/map_flatten_fixable.rs +++ b/tests/ui/map_flatten_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::pedantic)] #![allow(clippy::let_underscore_untyped)] diff --git a/tests/ui/map_identity.fixed b/tests/ui/map_identity.fixed index 2256e51f2d09..7fb7d8c12188 100644 --- a/tests/ui/map_identity.fixed +++ b/tests/ui/map_identity.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_identity)] #![allow(clippy::needless_return)] diff --git a/tests/ui/map_identity.rs b/tests/ui/map_identity.rs index ccfdc9ea76d5..7891c2426283 100644 --- a/tests/ui/map_identity.rs +++ b/tests/ui/map_identity.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_identity)] #![allow(clippy::needless_return)] diff --git a/tests/ui/map_unwrap_or.rs b/tests/ui/map_unwrap_or.rs index 32631024ca5d..205cb1cd1de1 100644 --- a/tests/ui/map_unwrap_or.rs +++ b/tests/ui/map_unwrap_or.rs @@ -1,4 +1,4 @@ -// aux-build:option_helpers.rs +//@aux-build:option_helpers.rs #![warn(clippy::map_unwrap_or)] #![allow(clippy::uninlined_format_args, clippy::unnecessary_lazy_evaluations)] @@ -56,6 +56,10 @@ fn option_methods() { .unwrap_or_else(|| 0 ); + + // Check for `map(f).unwrap_or(false)` use. + let _ = opt.map(|x| x > 5).unwrap_or(false); + } #[rustfmt::skip] @@ -94,3 +98,55 @@ fn msrv_1_41() { let _ = res.map(|x| x + 1).unwrap_or_else(|_e| 0); } + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> c60222dc1 (changed the msrv to 1.70 to suggest `is_some_and`) +#[clippy::msrv = "1.69"] +fn msrv_1_69() { + let opt: Option = Some(1); + + let _ = opt.map(|x| x > 5).unwrap_or(false); +} + +#[clippy::msrv = "1.70"] +fn msrv_1_70() { + let opt: Option = Some(1); + + let _ = opt.map(|x| x > 5).unwrap_or(false); +} + +<<<<<<< HEAD +======= +>>>>>>> 9d58a4262 ([`map_unwrap_or`]: don't lint when referenced variable is moved) +======= +>>>>>>> c60222dc1 (changed the msrv to 1.70 to suggest `is_some_and`) +mod issue_10579 { + // Different variations of the same issue. + fn v1() { + let x = vec![1, 2, 3, 0]; + let y = x.strip_suffix(&[0]).map(|s| s.to_vec()).unwrap_or(x); + println!("{y:?}"); + } + fn v2() { + let x = vec![1, 2, 3, 0]; + let y = Some(()).map(|_| x.to_vec()).unwrap_or(x); + println!("{y:?}"); + } + fn v3() { + let x = vec![1, 2, 3, 0]; + let xref = &x; + let y = Some(()).map(|_| xref.to_vec()).unwrap_or(x); + println!("{y:?}"); + } + fn v4() { + struct VecInStruct { + v: Vec, + } + let s = VecInStruct { v: vec![1, 2, 3, 0] }; + + let y = Some(()).map(|_| s.v.clone()).unwrap_or(s.v); + println!("{y:?}"); + } +} diff --git a/tests/ui/map_unwrap_or.stderr b/tests/ui/map_unwrap_or.stderr index 41781b050fa2..de2e9fa5cb88 100644 --- a/tests/ui/map_unwrap_or.stderr +++ b/tests/ui/map_unwrap_or.stderr @@ -126,8 +126,20 @@ LL | | 0 LL | | ); | |_________^ +error: called `map().unwrap_or(false)` on an `Option` value. This can be done more directly by calling `is_some_and()` instead + --> $DIR/map_unwrap_or.rs:61:13 + | +LL | let _ = opt.map(|x| x > 5).unwrap_or(false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_some_and()` instead + | +LL - let _ = opt.map(|x| x > 5).unwrap_or(false); +LL + let _ = opt.is_some_and(|x| x > 5); + | + error: called `map().unwrap_or_else()` on a `Result` value. This can be done more directly by calling `.map_or_else(, )` instead - --> $DIR/map_unwrap_or.rs:67:13 + --> $DIR/map_unwrap_or.rs:71:13 | LL | let _ = res.map(|x| { | _____________^ @@ -137,7 +149,7 @@ LL | | ).unwrap_or_else(|_e| 0); | |____________________________^ error: called `map().unwrap_or_else()` on a `Result` value. This can be done more directly by calling `.map_or_else(, )` instead - --> $DIR/map_unwrap_or.rs:71:13 + --> $DIR/map_unwrap_or.rs:75:13 | LL | let _ = res.map(|x| x + 1) | _____________^ @@ -147,10 +159,44 @@ LL | | }); | |__________^ error: called `map().unwrap_or_else()` on a `Result` value. This can be done more directly by calling `.map_or_else(, )` instead - --> $DIR/map_unwrap_or.rs:95:13 + --> $DIR/map_unwrap_or.rs:99:13 | LL | let _ = res.map(|x| x + 1).unwrap_or_else(|_e| 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `res.map_or_else(|_e| 0, |x| x + 1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or_else(|_e| 0, |x| x + 1)` + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> c60222dc1 (changed the msrv to 1.70 to suggest `is_some_and`) +error: called `map().unwrap_or()` on an `Option` value. This can be done more directly by calling `map_or(, )` instead + --> $DIR/map_unwrap_or.rs:106:13 + | +LL | let _ = opt.map(|x| x > 5).unwrap_or(false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `map_or(, )` instead + | +LL - let _ = opt.map(|x| x > 5).unwrap_or(false); +LL + let _ = opt.map_or(false, |x| x > 5); + | + +error: called `map().unwrap_or(false)` on an `Option` value. This can be done more directly by calling `is_some_and()` instead + --> $DIR/map_unwrap_or.rs:113:13 + | +LL | let _ = opt.map(|x| x > 5).unwrap_or(false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_some_and()` instead + | +LL - let _ = opt.map(|x| x > 5).unwrap_or(false); +LL + let _ = opt.is_some_and(|x| x > 5); + | -error: aborting due to 12 previous errors +error: aborting due to 15 previous errors +<<<<<<< HEAD +======= +error: aborting due to 13 previous errors +>>>>>>> 9b7d8d1dc (suggests `is_some_and` over `map().unwrap_or(false)`) +======= +>>>>>>> c60222dc1 (changed the msrv to 1.70 to suggest `is_some_and`) diff --git a/tests/ui/map_unwrap_or_fixable.fixed b/tests/ui/map_unwrap_or_fixable.fixed index bd5b4f7165a4..ea5b6a6691e5 100644 --- a/tests/ui/map_unwrap_or_fixable.fixed +++ b/tests/ui/map_unwrap_or_fixable.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::map_unwrap_or)] diff --git a/tests/ui/map_unwrap_or_fixable.rs b/tests/ui/map_unwrap_or_fixable.rs index 0b892caf20e8..f8bb9d8ca6a3 100644 --- a/tests/ui/map_unwrap_or_fixable.rs +++ b/tests/ui/map_unwrap_or_fixable.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::map_unwrap_or)] diff --git a/tests/ui/map_unwrap_or_fixable.stderr b/tests/ui/map_unwrap_or_fixable.stderr index 1837bc2ca3b8..71dc009f2ce6 100644 --- a/tests/ui/map_unwrap_or_fixable.stderr +++ b/tests/ui/map_unwrap_or_fixable.stderr @@ -5,7 +5,7 @@ LL | let _ = opt.map(|x| x + 1) | _____________^ LL | | // Should lint even though this call is on a separate line. LL | | .unwrap_or_else(|| 0); - | |_____________________________^ help: try this: `opt.map_or_else(|| 0, |x| x + 1)` + | |_____________________________^ help: try: `opt.map_or_else(|| 0, |x| x + 1)` | = note: `-D clippy::map-unwrap-or` implied by `-D warnings` @@ -16,7 +16,7 @@ LL | let _ = res.map(|x| x + 1) | _____________^ LL | | // should lint even though this call is on a separate line LL | | .unwrap_or_else(|_e| 0); - | |_______________________________^ help: try this: `res.map_or_else(|_e| 0, |x| x + 1)` + | |_______________________________^ help: try: `res.map_or_else(|_e| 0, |x| x + 1)` error: aborting due to 2 previous errors diff --git a/tests/ui/match_as_ref.fixed b/tests/ui/match_as_ref.fixed index ddfa1e741ada..61d414bdf4be 100644 --- a/tests/ui/match_as_ref.fixed +++ b/tests/ui/match_as_ref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::match_as_ref)] @@ -12,7 +12,9 @@ fn match_as_ref() { } mod issue4437 { - use std::{error::Error, fmt, num::ParseIntError}; + use std::error::Error; + use std::fmt; + use std::num::ParseIntError; #[derive(Debug)] struct E { diff --git a/tests/ui/match_as_ref.rs b/tests/ui/match_as_ref.rs index 025d475ae13d..cd39514c59ac 100644 --- a/tests/ui/match_as_ref.rs +++ b/tests/ui/match_as_ref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::match_as_ref)] @@ -18,7 +18,9 @@ fn match_as_ref() { } mod issue4437 { - use std::{error::Error, fmt, num::ParseIntError}; + use std::error::Error; + use std::fmt; + use std::num::ParseIntError; #[derive(Debug)] struct E { diff --git a/tests/ui/match_as_ref.stderr b/tests/ui/match_as_ref.stderr index c3b62849cb33..2e6955eb8056 100644 --- a/tests/ui/match_as_ref.stderr +++ b/tests/ui/match_as_ref.stderr @@ -6,7 +6,7 @@ LL | let borrowed: Option<&()> = match owned { LL | | None => None, LL | | Some(ref v) => Some(v), LL | | }; - | |_____^ help: try this: `owned.as_ref()` + | |_____^ help: try: `owned.as_ref()` | = note: `-D clippy::match-as-ref` implied by `-D warnings` @@ -18,16 +18,16 @@ LL | let borrow_mut: Option<&mut ()> = match mut_owned { LL | | None => None, LL | | Some(ref mut v) => Some(v), LL | | }; - | |_____^ help: try this: `mut_owned.as_mut()` + | |_____^ help: try: `mut_owned.as_mut()` error: use `as_ref()` instead - --> $DIR/match_as_ref.rs:30:13 + --> $DIR/match_as_ref.rs:32:13 | LL | / match self.source { LL | | Some(ref s) => Some(s), LL | | None => None, LL | | } - | |_____________^ help: try this: `self.source.as_ref().map(|x| x as _)` + | |_____________^ help: try: `self.source.as_ref().map(|x| x as _)` error: aborting due to 3 previous errors diff --git a/tests/ui/match_expr_like_matches_macro.fixed b/tests/ui/match_expr_like_matches_macro.fixed index 55cd15bd5c38..60f590661735 100644 --- a/tests/ui/match_expr_like_matches_macro.fixed +++ b/tests/ui/match_expr_like_matches_macro.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_like_matches_macro)] #![allow( @@ -15,7 +15,7 @@ fn main() { let _y = matches!(x, Some(0)); // Lint - let _w = matches!(x, Some(_)); + let _w = x.is_some(); // Turn into is_none let _z = x.is_none(); diff --git a/tests/ui/match_expr_like_matches_macro.rs b/tests/ui/match_expr_like_matches_macro.rs index 5d645e108e51..afdf1069f5e4 100644 --- a/tests/ui/match_expr_like_matches_macro.rs +++ b/tests/ui/match_expr_like_matches_macro.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_like_matches_macro)] #![allow( diff --git a/tests/ui/match_expr_like_matches_macro.stderr b/tests/ui/match_expr_like_matches_macro.stderr index 46f67ef4900f..c8c1e5da05fe 100644 --- a/tests/ui/match_expr_like_matches_macro.stderr +++ b/tests/ui/match_expr_like_matches_macro.stderr @@ -6,11 +6,11 @@ LL | let _y = match x { LL | | Some(0) => true, LL | | _ => false, LL | | }; - | |_____^ help: try this: `matches!(x, Some(0))` + | |_____^ help: try: `matches!(x, Some(0))` | = note: `-D clippy::match-like-matches-macro` implied by `-D warnings` -error: match expression looks like `matches!` macro +error: redundant pattern matching, consider using `is_some()` --> $DIR/match_expr_like_matches_macro.rs:21:14 | LL | let _w = match x { @@ -18,7 +18,9 @@ LL | let _w = match x { LL | | Some(_) => true, LL | | _ => false, LL | | }; - | |_____^ help: try this: `matches!(x, Some(_))` + | |_____^ help: try: `x.is_some()` + | + = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` error: redundant pattern matching, consider using `is_none()` --> $DIR/match_expr_like_matches_macro.rs:27:14 @@ -28,9 +30,7 @@ LL | let _z = match x { LL | | Some(_) => false, LL | | None => true, LL | | }; - | |_____^ help: try this: `x.is_none()` - | - = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` + | |_____^ help: try: `x.is_none()` error: match expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:33:15 @@ -40,13 +40,13 @@ LL | let _zz = match x { LL | | Some(r) if r == 0 => false, LL | | _ => true, LL | | }; - | |_____^ help: try this: `!matches!(x, Some(r) if r == 0)` + | |_____^ help: try: `!matches!(x, Some(r) if r == 0)` error: if let .. else expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:39:16 | LL | let _zzz = if let Some(5) = x { true } else { false }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `matches!(x, Some(5))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(x, Some(5))` error: match expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:63:20 @@ -57,7 +57,7 @@ LL | | E::A(_) => true, LL | | E::B(_) => true, LL | | _ => false, LL | | }; - | |_________^ help: try this: `matches!(x, E::A(_) | E::B(_))` + | |_________^ help: try: `matches!(x, E::A(_) | E::B(_))` error: match expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:73:20 @@ -70,7 +70,7 @@ LL | | } LL | | E::B(_) => true, LL | | _ => false, LL | | }; - | |_________^ help: try this: `matches!(x, E::A(_) | E::B(_))` + | |_________^ help: try: `matches!(x, E::A(_) | E::B(_))` error: match expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:83:20 @@ -81,7 +81,7 @@ LL | | E::B(_) => false, LL | | E::C => false, LL | | _ => true, LL | | }; - | |_________^ help: try this: `!matches!(x, E::B(_) | E::C)` + | |_________^ help: try: `!matches!(x, E::B(_) | E::C)` error: match expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:143:18 @@ -91,7 +91,7 @@ LL | let _z = match &z { LL | | Some(3) => true, LL | | _ => false, LL | | }; - | |_________^ help: try this: `matches!(z, Some(3))` + | |_________^ help: try: `matches!(z, Some(3))` error: match expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:152:18 @@ -101,7 +101,7 @@ LL | let _z = match &z { LL | | Some(3) => true, LL | | _ => false, LL | | }; - | |_________^ help: try this: `matches!(&z, Some(3))` + | |_________^ help: try: `matches!(&z, Some(3))` error: match expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:169:21 @@ -111,7 +111,7 @@ LL | let _ = match &z { LL | | AnEnum::X => true, LL | | _ => false, LL | | }; - | |_____________^ help: try this: `matches!(&z, AnEnum::X)` + | |_____________^ help: try: `matches!(&z, AnEnum::X)` error: match expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:183:20 @@ -121,7 +121,7 @@ LL | let _res = match &val { LL | | &Some(ref _a) => true, LL | | _ => false, LL | | }; - | |_________^ help: try this: `matches!(&val, &Some(ref _a))` + | |_________^ help: try: `matches!(&val, &Some(ref _a))` error: match expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:195:20 @@ -131,7 +131,7 @@ LL | let _res = match &val { LL | | &Some(ref _a) => true, LL | | _ => false, LL | | }; - | |_________^ help: try this: `matches!(&val, &Some(ref _a))` + | |_________^ help: try: `matches!(&val, &Some(ref _a))` error: match expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:253:14 @@ -141,7 +141,7 @@ LL | let _y = match Some(5) { LL | | Some(0) => true, LL | | _ => false, LL | | }; - | |_____^ help: try this: `matches!(Some(5), Some(0))` + | |_____^ help: try: `matches!(Some(5), Some(0))` error: aborting due to 14 previous errors diff --git a/tests/ui/match_on_vec_items.rs b/tests/ui/match_on_vec_items.rs index 30415e3b94dc..a902cad70a73 100644 --- a/tests/ui/match_on_vec_items.rs +++ b/tests/ui/match_on_vec_items.rs @@ -1,4 +1,17 @@ #![warn(clippy::match_on_vec_items)] +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::redundant_at_rest_pattern, clippy::useless_vec)] +======= +#![allow(clippy::useless_vec)] +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +#![allow(clippy::redundant_rest_pattern, clippy::useless_vec)] +>>>>>>> 9a8347ded (New lint [`redundant_rest_pattern`]) +======= +#![allow(clippy::redundant_at_rest_pattern, clippy::useless_vec)] +>>>>>>> e9ced1251 (Rename the lint) fn match_with_wildcard() { let arr = vec![0, 1, 2, 3]; diff --git a/tests/ui/match_on_vec_items.stderr b/tests/ui/match_on_vec_items.stderr index 49446d715abe..fc4a3ce19463 100644 --- a/tests/ui/match_on_vec_items.stderr +++ b/tests/ui/match_on_vec_items.stderr @@ -1,52 +1,52 @@ error: indexing into a vector may panic - --> $DIR/match_on_vec_items.rs:9:11 + --> $DIR/match_on_vec_items.rs:10:11 | LL | match arr[idx] { - | ^^^^^^^^ help: try this: `arr.get(idx)` + | ^^^^^^^^ help: try: `arr.get(idx)` | = note: `-D clippy::match-on-vec-items` implied by `-D warnings` error: indexing into a vector may panic - --> $DIR/match_on_vec_items.rs:16:11 + --> $DIR/match_on_vec_items.rs:17:11 | LL | match arr[range] { - | ^^^^^^^^^^ help: try this: `arr.get(range)` + | ^^^^^^^^^^ help: try: `arr.get(range)` error: indexing into a vector may panic - --> $DIR/match_on_vec_items.rs:29:11 + --> $DIR/match_on_vec_items.rs:30:11 | LL | match arr[idx] { - | ^^^^^^^^ help: try this: `arr.get(idx)` + | ^^^^^^^^ help: try: `arr.get(idx)` error: indexing into a vector may panic - --> $DIR/match_on_vec_items.rs:36:11 + --> $DIR/match_on_vec_items.rs:37:11 | LL | match arr[range] { - | ^^^^^^^^^^ help: try this: `arr.get(range)` + | ^^^^^^^^^^ help: try: `arr.get(range)` error: indexing into a vector may panic - --> $DIR/match_on_vec_items.rs:49:11 + --> $DIR/match_on_vec_items.rs:50:11 | LL | match arr[idx] { - | ^^^^^^^^ help: try this: `arr.get(idx)` + | ^^^^^^^^ help: try: `arr.get(idx)` error: indexing into a vector may panic - --> $DIR/match_on_vec_items.rs:56:11 + --> $DIR/match_on_vec_items.rs:57:11 | LL | match arr[range] { - | ^^^^^^^^^^ help: try this: `arr.get(range)` + | ^^^^^^^^^^ help: try: `arr.get(range)` error: indexing into a vector may panic - --> $DIR/match_on_vec_items.rs:69:11 + --> $DIR/match_on_vec_items.rs:70:11 | LL | match arr[idx] { - | ^^^^^^^^ help: try this: `arr.get(idx)` + | ^^^^^^^^ help: try: `arr.get(idx)` error: indexing into a vector may panic - --> $DIR/match_on_vec_items.rs:76:11 + --> $DIR/match_on_vec_items.rs:77:11 | LL | match arr[range] { - | ^^^^^^^^^^ help: try this: `arr.get(range)` + | ^^^^^^^^^^ help: try: `arr.get(range)` error: aborting due to 8 previous errors diff --git a/tests/ui/match_overlapping_arm.rs b/tests/ui/match_overlapping_arm.rs index b4097fa96045..b78c1fd06d44 100644 --- a/tests/ui/match_overlapping_arm.rs +++ b/tests/ui/match_overlapping_arm.rs @@ -1,7 +1,7 @@ #![feature(exclusive_range_pattern)] #![warn(clippy::match_overlapping_arm)] #![allow(clippy::redundant_pattern_matching)] -#![allow(clippy::if_same_then_else, clippy::equatable_if_let)] +#![allow(clippy::if_same_then_else, clippy::equatable_if_let, clippy::needless_if)] /// Tests for match_overlapping_arm diff --git a/tests/ui/match_ref_pats.fixed b/tests/ui/match_ref_pats.fixed index cf37fc6dc90a..50c3dcc1e0a8 100644 --- a/tests/ui/match_ref_pats.fixed +++ b/tests/ui/match_ref_pats.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_ref_pats)] #![allow(dead_code, unused_variables)] #![allow(clippy::enum_variant_names, clippy::equatable_if_let, clippy::uninlined_format_args)] diff --git a/tests/ui/match_ref_pats.rs b/tests/ui/match_ref_pats.rs index 3220b97d1b51..d29ddacc04ad 100644 --- a/tests/ui/match_ref_pats.rs +++ b/tests/ui/match_ref_pats.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_ref_pats)] #![allow(dead_code, unused_variables)] #![allow(clippy::enum_variant_names, clippy::equatable_if_let, clippy::uninlined_format_args)] diff --git a/tests/ui/match_ref_pats.stderr b/tests/ui/match_ref_pats.stderr index 7d9646c842ee..1294e0fe56fd 100644 --- a/tests/ui/match_ref_pats.stderr +++ b/tests/ui/match_ref_pats.stderr @@ -35,7 +35,7 @@ error: redundant pattern matching, consider using `is_none()` --> $DIR/match_ref_pats.rs:38:12 | LL | if let &None = a { - | -------^^^^^---- help: try this: `if a.is_none()` + | -------^^^^^---- help: try: `if a.is_none()` | = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` @@ -43,7 +43,7 @@ error: redundant pattern matching, consider using `is_none()` --> $DIR/match_ref_pats.rs:43:12 | LL | if let &None = &b { - | -------^^^^^----- help: try this: `if b.is_none()` + | -------^^^^^----- help: try: `if b.is_none()` error: you don't need to add `&` to all patterns --> $DIR/match_ref_pats.rs:103:9 diff --git a/tests/ui/match_result_ok.fixed b/tests/ui/match_result_ok.fixed index 10ae1ee5245e..fe67b225fa17 100644 --- a/tests/ui/match_result_ok.fixed +++ b/tests/ui/match_result_ok.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_result_ok)] #![allow(dead_code)] #![allow(clippy::boxed_local, clippy::uninlined_format_args)] diff --git a/tests/ui/match_result_ok.rs b/tests/ui/match_result_ok.rs index bc2c4b50e272..eac382e1f623 100644 --- a/tests/ui/match_result_ok.rs +++ b/tests/ui/match_result_ok.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_result_ok)] #![allow(dead_code)] #![allow(clippy::boxed_local, clippy::uninlined_format_args)] diff --git a/tests/ui/match_same_arms.rs b/tests/ui/match_same_arms.rs index 0b9342c9c423..b8a2e0732557 100644 --- a/tests/ui/match_same_arms.rs +++ b/tests/ui/match_same_arms.rs @@ -8,29 +8,30 @@ pub enum Abc { fn match_same_arms() { let _ = match Abc::A { - Abc::A => 0, + Abc::A => 0, //~ ERROR: this match arm has an identical body to the `_` wildcard arm Abc::B => 1, - _ => 0, //~ ERROR match arms have same body + _ => 0, }; match (1, 2, 3) { - (1, .., 3) => 42, - (.., 3) => 42, //~ ERROR match arms have same body + (1, .., 3) => 42, //~ ERROR: this match arm has an identical body to another arm + (.., 3) => 42, _ => 0, }; let _ = match 42 { 42 => 1, - 51 => 1, //~ ERROR match arms have same body - 41 => 2, - 52 => 2, //~ ERROR match arms have same body + 51 => 1, //~ ERROR: this match arm has an identical body to another arm + 41 => 2, //~ ERROR: this match arm has an identical body to another arm + 52 => 2, _ => 0, }; let _ = match 42 { 1 => 2, - 2 => 2, //~ ERROR 2nd matched arms have same body - 3 => 2, //~ ERROR 3rd matched arms have same body + 2 => 2, //~ ERROR: this match arm has an identical body to another arm + //~^ ERROR: this match arm has an identical body to another arm + 3 => 2, //~ ERROR: this match arm has an identical body to another arm 4 => 3, _ => 0, }; @@ -48,9 +49,117 @@ mod issue4244 { match self { CommandInfo::BuiltIn { name, .. } => name.to_string(), CommandInfo::External { name, .. } => name.to_string(), + //~^ ERROR: this match arm has an identical body to another arm } } } } -fn main() {} +macro_rules! m { + (foo) => {}; + (bar) => {}; +} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +macro_rules! foo { + () => { + 1 + }; +} +macro_rules! bar { + () => { + 1 + }; +} +<<<<<<< HEAD +======= +>>>>>>> 0b3c2ed81 (Search for inactive `cfg` attributes and empty macro expansion through) +======= +>>>>>>> 58132cb3b (Improve `SpanlessEq`) + +fn main() { + let x = 0; + let _ = match 0 { + 0 => { + m!(foo); + x + }, + 1 => { + m!(bar); + x + }, + _ => 1, + }; + + let _ = match 0 { + 0 => { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) + m!(foo); + 0 + }, + 1 => { + m!(bar); + 0 + }, + _ => 1, + }; + + let _ = match 0 { + 0 => { +<<<<<<< HEAD +======= +>>>>>>> 0b3c2ed81 (Search for inactive `cfg` attributes and empty macro expansion through) +======= +>>>>>>> 535117074 (Slightly refactor constant evaluation and add detection for empty macro expansion and `cfg`ed statements.) + let mut x = 0; + #[cfg(not_enabled)] + { + x = 5; + } + #[cfg(not(not_enabled))] + { + x = 6; + } + x + }, + 1 => { + let mut x = 0; + #[cfg(also_not_enabled)] + { + x = 5; + } + #[cfg(not(also_not_enabled))] + { + x = 6; + } + x + }, + _ => 0, + }; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 58132cb3b (Improve `SpanlessEq`) + + let _ = match 0 { + 0 => foo!(), + 1 => bar!(), + _ => 1, + }; + + let _ = match 0 { + 0 => cfg!(not_enabled), + 1 => cfg!(also_not_enabled), + _ => false, + }; +<<<<<<< HEAD +======= +>>>>>>> 0b3c2ed81 (Search for inactive `cfg` attributes and empty macro expansion through) +======= +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +} diff --git a/tests/ui/match_same_arms.stderr b/tests/ui/match_same_arms.stderr index db85b5964e84..88b9a20a3726 100644 --- a/tests/ui/match_same_arms.stderr +++ b/tests/ui/match_same_arms.stderr @@ -8,7 +8,7 @@ LL | Abc::A => 0, note: `_` wildcard arm here --> $DIR/match_same_arms.rs:13:9 | -LL | _ => 0, //~ ERROR match arms have same body +LL | _ => 0, | ^^^^^^ = note: `-D clippy::match-same-arms` implied by `-D warnings` @@ -24,13 +24,13 @@ LL | (1, .., 3) => 42, note: other arm here --> $DIR/match_same_arms.rs:18:9 | -LL | (.., 3) => 42, //~ ERROR match arms have same body +LL | (.., 3) => 42, | ^^^^^^^^^^^^^ error: this match arm has an identical body to another arm --> $DIR/match_same_arms.rs:24:9 | -LL | 51 => 1, //~ ERROR match arms have same body +LL | 51 => 1, | --^^^^^ | | | help: try merging the arm patterns: `51 | 42` @@ -54,13 +54,13 @@ LL | 41 => 2, note: other arm here --> $DIR/match_same_arms.rs:26:9 | -LL | 52 => 2, //~ ERROR match arms have same body +LL | 52 => 2, | ^^^^^^^ error: this match arm has an identical body to another arm --> $DIR/match_same_arms.rs:32:9 | -LL | 2 => 2, //~ ERROR 2nd matched arms have same body +LL | 2 => 2, | -^^^^^ | | | help: try merging the arm patterns: `2 | 1` @@ -73,9 +73,9 @@ LL | 1 => 2, | ^^^^^^ error: this match arm has an identical body to another arm - --> $DIR/match_same_arms.rs:33:9 + --> $DIR/match_same_arms.rs:34:9 | -LL | 3 => 2, //~ ERROR 3rd matched arms have same body +LL | 3 => 2, | -^^^^^ | | | help: try merging the arm patterns: `3 | 1` @@ -90,20 +90,20 @@ LL | 1 => 2, error: this match arm has an identical body to another arm --> $DIR/match_same_arms.rs:32:9 | -LL | 2 => 2, //~ ERROR 2nd matched arms have same body +LL | 2 => 2, | -^^^^^ | | | help: try merging the arm patterns: `2 | 3` | = help: or try changing either arm body note: other arm here - --> $DIR/match_same_arms.rs:33:9 + --> $DIR/match_same_arms.rs:34:9 | -LL | 3 => 2, //~ ERROR 3rd matched arms have same body +LL | 3 => 2, | ^^^^^^ error: this match arm has an identical body to another arm - --> $DIR/match_same_arms.rs:50:17 + --> $DIR/match_same_arms.rs:51:17 | LL | CommandInfo::External { name, .. } => name.to_string(), | ----------------------------------^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +112,7 @@ LL | CommandInfo::External { name, .. } => name.to_string(), | = help: or try changing either arm body note: other arm here - --> $DIR/match_same_arms.rs:49:17 + --> $DIR/match_same_arms.rs:50:17 | LL | CommandInfo::BuiltIn { name, .. } => name.to_string(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/match_same_arms2.rs b/tests/ui/match_same_arms2.rs index 82b2c433d99e..b1b9a6ae3e8a 100644 --- a/tests/ui/match_same_arms2.rs +++ b/tests/ui/match_same_arms2.rs @@ -13,6 +13,7 @@ fn foo() -> bool { fn match_same_arms() { let _ = match 42 { 42 => { + //~^ ERROR: this match arm has an identical body to the `_` wildcard arm foo(); let mut a = 42 + [23].len() as i32; if true { @@ -22,7 +23,6 @@ fn match_same_arms() { a }, _ => { - //~ ERROR match arms have same body foo(); let mut a = 42 + [23].len() as i32; if true { @@ -35,13 +35,13 @@ fn match_same_arms() { let _ = match 42 { 42 => foo(), - 51 => foo(), //~ ERROR match arms have same body + 51 => foo(), //~ ERROR: this match arm has an identical body to another arm _ => true, }; let _ = match Some(42) { Some(_) => 24, - None => 24, //~ ERROR match arms have same body + None => 24, //~ ERROR: this match arm has an identical body to another arm }; let _ = match Some(42) { @@ -63,13 +63,13 @@ fn match_same_arms() { match (Some(42), Some(42)) { (Some(a), None) => bar(a), - (None, Some(a)) => bar(a), //~ ERROR match arms have same body + (None, Some(a)) => bar(a), //~ ERROR: this match arm has an identical body to another arm _ => (), } match (Some(42), Some(42)) { - (Some(a), ..) => bar(a), - (.., Some(a)) => bar(a), //~ ERROR match arms have same body + (Some(a), ..) => bar(a), //~ ERROR: this match arm has an identical body to another arm + (.., Some(a)) => bar(a), _ => (), } @@ -102,7 +102,7 @@ fn match_same_arms() { } match (x, Some(1i32)) { - (Ok(x), Some(_)) => println!("ok {}", x), + (Ok(x), Some(_)) => println!("ok {}", x), //~ ERROR: this match arm has an identical body to another arm (Ok(_), Some(x)) => println!("ok {}", x), _ => println!("err"), } @@ -118,7 +118,7 @@ fn match_same_arms() { match x { Ok(_tmp) => println!("ok"), Ok(3) => println!("ok"), - Ok(_) => println!("ok"), + Ok(_) => println!("ok"), //~ ERROR: this match arm has an identical body to another arm Err(_) => { unreachable!(); }, @@ -146,6 +146,7 @@ fn match_same_arms() { empty!(0); }, 1 => { + //~^ ERROR: this match arm has an identical body to another arm empty!(0); }, x => { @@ -195,7 +196,7 @@ fn main() { // Suggest moving `Foo::Z(_)` up. let _ = match Foo::X(0) { - Foo::X(0) => 1, + Foo::X(0) => 1, //~ ERROR: this match arm has an identical body to another arm Foo::X(_) | Foo::Y(_) => 2, Foo::Z(_) => 1, _ => 0, @@ -205,7 +206,7 @@ fn main() { let _ = match Foo::X(0) { Foo::X(0) => 1, Foo::Y(_) | Foo::Z(0) => 2, - Foo::Z(_) => 1, + Foo::Z(_) => 1, //~ ERROR: this match arm has an identical body to another arm _ => 0, }; @@ -228,7 +229,7 @@ fn main() { Some(Bar { x: 0, y: 5, .. }) => 1, Some(Bar { y: 10, z: 0, .. }) => 2, None => 50, - Some(Bar { y: 0, x: 5, .. }) => 1, + Some(Bar { y: 0, x: 5, .. }) => 1, //~ ERROR: this match arm has an identical body to another arm _ => 200, }; @@ -239,4 +240,10 @@ fn main() { 3 => core::convert::identity::(todo!()), _ => 5, }; + + let _ = match 0 { + 0 => cfg!(not_enable), + 1 => cfg!(not_enable), + _ => false, + }; } diff --git a/tests/ui/match_same_arms2.stderr b/tests/ui/match_same_arms2.stderr index 06cd4300054d..5ab78179054d 100644 --- a/tests/ui/match_same_arms2.stderr +++ b/tests/ui/match_same_arms2.stderr @@ -2,9 +2,9 @@ error: this match arm has an identical body to the `_` wildcard arm --> $DIR/match_same_arms2.rs:15:9 | LL | / 42 => { +LL | | LL | | foo(); LL | | let mut a = 42 + [23].len() as i32; -LL | | if true { ... | LL | | a LL | | }, @@ -12,12 +12,12 @@ LL | | }, | = help: or try changing either arm body note: `_` wildcard arm here - --> $DIR/match_same_arms2.rs:24:9 + --> $DIR/match_same_arms2.rs:25:9 | LL | / _ => { -LL | | //~ ERROR match arms have same body LL | | foo(); LL | | let mut a = 42 + [23].len() as i32; +LL | | if true { ... | LL | | a LL | | }, @@ -27,7 +27,7 @@ LL | | }, error: this match arm has an identical body to another arm --> $DIR/match_same_arms2.rs:38:9 | -LL | 51 => foo(), //~ ERROR match arms have same body +LL | 51 => foo(), | --^^^^^^^^^ | | | help: try merging the arm patterns: `51 | 42` @@ -42,7 +42,7 @@ LL | 42 => foo(), error: this match arm has an identical body to another arm --> $DIR/match_same_arms2.rs:44:9 | -LL | None => 24, //~ ERROR match arms have same body +LL | None => 24, | ----^^^^^^ | | | help: try merging the arm patterns: `None | Some(_)` @@ -57,7 +57,7 @@ LL | Some(_) => 24, error: this match arm has an identical body to another arm --> $DIR/match_same_arms2.rs:66:9 | -LL | (None, Some(a)) => bar(a), //~ ERROR match arms have same body +LL | (None, Some(a)) => bar(a), | ---------------^^^^^^^^^^ | | | help: try merging the arm patterns: `(None, Some(a)) | (Some(a), None)` @@ -81,7 +81,7 @@ LL | (Some(a), ..) => bar(a), note: other arm here --> $DIR/match_same_arms2.rs:72:9 | -LL | (.., Some(a)) => bar(a), //~ ERROR match arms have same body +LL | (.., Some(a)) => bar(a), | ^^^^^^^^^^^^^^^^^^^^^^^ error: this match arm has an identical body to another arm @@ -121,6 +121,7 @@ LL | 1 => { | ^ help: try merging the arm patterns: `1 | 0` | _________| | | +LL | | LL | | empty!(0); LL | | }, | |_________^ @@ -135,7 +136,7 @@ LL | | }, | |_________^ error: match expression looks like `matches!` macro - --> $DIR/match_same_arms2.rs:166:16 + --> $DIR/match_same_arms2.rs:167:16 | LL | let _ans = match x { | ________________^ @@ -143,12 +144,12 @@ LL | | E::A => false, LL | | E::B => false, LL | | _ => true, LL | | }; - | |_____^ help: try this: `!matches!(x, E::A | E::B)` + | |_____^ help: try: `!matches!(x, E::A | E::B)` | = note: `-D clippy::match-like-matches-macro` implied by `-D warnings` error: this match arm has an identical body to another arm - --> $DIR/match_same_arms2.rs:198:9 + --> $DIR/match_same_arms2.rs:199:9 | LL | Foo::X(0) => 1, | ---------^^^^^ @@ -157,13 +158,13 @@ LL | Foo::X(0) => 1, | = help: or try changing either arm body note: other arm here - --> $DIR/match_same_arms2.rs:200:9 + --> $DIR/match_same_arms2.rs:201:9 | LL | Foo::Z(_) => 1, | ^^^^^^^^^^^^^^ error: this match arm has an identical body to another arm - --> $DIR/match_same_arms2.rs:208:9 + --> $DIR/match_same_arms2.rs:209:9 | LL | Foo::Z(_) => 1, | ---------^^^^^ @@ -172,13 +173,13 @@ LL | Foo::Z(_) => 1, | = help: or try changing either arm body note: other arm here - --> $DIR/match_same_arms2.rs:206:9 + --> $DIR/match_same_arms2.rs:207:9 | LL | Foo::X(0) => 1, | ^^^^^^^^^^^^^^ error: this match arm has an identical body to another arm - --> $DIR/match_same_arms2.rs:231:9 + --> $DIR/match_same_arms2.rs:232:9 | LL | Some(Bar { y: 0, x: 5, .. }) => 1, | ----------------------------^^^^^ @@ -187,10 +188,41 @@ LL | Some(Bar { y: 0, x: 5, .. }) => 1, | = help: or try changing either arm body note: other arm here - --> $DIR/match_same_arms2.rs:228:9 + --> $DIR/match_same_arms2.rs:229:9 | LL | Some(Bar { x: 0, y: 5, .. }) => 1, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: this match arm has an identical body to another arm +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/match_same_arms2.rs:246:9 +======= + --> $DIR/match_same_arms2.rs:245:9 +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + --> $DIR/match_same_arms2.rs:246:9 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | 1 => cfg!(not_enable), + | -^^^^^^^^^^^^^^^^^^^^ + | | + | help: try merging the arm patterns: `1 | 0` + | + = help: or try changing either arm body +note: other arm here +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/match_same_arms2.rs:245:9 +======= + --> $DIR/match_same_arms2.rs:244:9 +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= + --> $DIR/match_same_arms2.rs:245:9 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | 0 => cfg!(not_enable), + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 13 previous errors diff --git a/tests/ui/match_same_arms_non_exhaustive.rs b/tests/ui/match_same_arms_non_exhaustive.rs new file mode 100644 index 000000000000..07421173a338 --- /dev/null +++ b/tests/ui/match_same_arms_non_exhaustive.rs @@ -0,0 +1,58 @@ +#![feature(non_exhaustive_omitted_patterns_lint)] +#![warn(clippy::match_same_arms)] +#![no_main] + +use std::sync::atomic::Ordering; // #[non_exhaustive] enum + +pub fn f(x: Ordering) { + match x { + Ordering::Relaxed => println!("relaxed"), + Ordering::Release => println!("release"), + Ordering::Acquire => println!("acquire"), + Ordering::AcqRel | Ordering::SeqCst => panic!(), + #[deny(non_exhaustive_omitted_patterns)] + _ => panic!(), + } +} + +mod f { + #![deny(non_exhaustive_omitted_patterns)] + + use super::*; + + pub fn f(x: Ordering) { + match x { + Ordering::Relaxed => println!("relaxed"), + Ordering::Release => println!("release"), + Ordering::Acquire => println!("acquire"), + Ordering::AcqRel | Ordering::SeqCst => panic!(), + _ => panic!(), + } + } +} + +// Below should still lint + +pub fn g(x: Ordering) { + match x { + Ordering::Relaxed => println!("relaxed"), + Ordering::Release => println!("release"), + Ordering::Acquire => println!("acquire"), + Ordering::AcqRel | Ordering::SeqCst => panic!(), + _ => panic!(), + } +} + +mod g { + use super::*; + + pub fn g(x: Ordering) { + match x { + Ordering::Relaxed => println!("relaxed"), + Ordering::Release => println!("release"), + Ordering::Acquire => println!("acquire"), + Ordering::AcqRel | Ordering::SeqCst => panic!(), + _ => panic!(), + } + } +} diff --git a/tests/ui/match_same_arms_non_exhaustive.stderr b/tests/ui/match_same_arms_non_exhaustive.stderr new file mode 100644 index 000000000000..088f7d5c0624 --- /dev/null +++ b/tests/ui/match_same_arms_non_exhaustive.stderr @@ -0,0 +1,29 @@ +error: this match arm has an identical body to the `_` wildcard arm + --> $DIR/match_same_arms_non_exhaustive.rs:41:9 + | +LL | Ordering::AcqRel | Ordering::SeqCst => panic!(), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm + | + = help: or try changing either arm body +note: `_` wildcard arm here + --> $DIR/match_same_arms_non_exhaustive.rs:42:9 + | +LL | _ => panic!(), + | ^^^^^^^^^^^^^ + = note: `-D clippy::match-same-arms` implied by `-D warnings` + +error: this match arm has an identical body to the `_` wildcard arm + --> $DIR/match_same_arms_non_exhaustive.rs:54:13 + | +LL | Ordering::AcqRel | Ordering::SeqCst => panic!(), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm + | + = help: or try changing either arm body +note: `_` wildcard arm here + --> $DIR/match_same_arms_non_exhaustive.rs:55:13 + | +LL | _ => panic!(), + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/match_single_binding.fixed b/tests/ui/match_single_binding.fixed index 201301cc9b73..f59ff456bf29 100644 --- a/tests/ui/match_single_binding.fixed +++ b/tests/ui/match_single_binding.fixed @@ -1,11 +1,12 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_single_binding)] #![allow( unused, clippy::let_unit_value, clippy::no_effect, clippy::toplevel_ref_arg, - clippy::uninlined_format_args + clippy::uninlined_format_args, + clippy::useless_vec )] struct Point { diff --git a/tests/ui/match_single_binding.rs b/tests/ui/match_single_binding.rs index 8b047b19ce96..e293bc33c8a9 100644 --- a/tests/ui/match_single_binding.rs +++ b/tests/ui/match_single_binding.rs @@ -1,11 +1,12 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_single_binding)] #![allow( unused, clippy::let_unit_value, clippy::no_effect, clippy::toplevel_ref_arg, - clippy::uninlined_format_args + clippy::uninlined_format_args, + clippy::useless_vec )] struct Point { diff --git a/tests/ui/match_single_binding.stderr b/tests/ui/match_single_binding.stderr index 9d16af76c6af..8998786de7ea 100644 --- a/tests/ui/match_single_binding.stderr +++ b/tests/ui/match_single_binding.stderr @@ -1,5 +1,5 @@ error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:33:5 + --> $DIR/match_single_binding.rs:34:5 | LL | / match (a, b, c) { LL | | (x, y, z) => { @@ -18,7 +18,7 @@ LL + } | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:39:5 + --> $DIR/match_single_binding.rs:40:5 | LL | / match (a, b, c) { LL | | (x, y, z) => println!("{} {} {}", x, y, z), @@ -32,7 +32,7 @@ LL + println!("{} {} {}", x, y, z); | error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:56:5 + --> $DIR/match_single_binding.rs:57:5 | LL | / match a { LL | | _ => println!("whatever"), @@ -40,7 +40,7 @@ LL | | } | |_____^ help: consider using the match body instead: `println!("whatever");` error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:60:5 + --> $DIR/match_single_binding.rs:61:5 | LL | / match a { LL | | _ => { @@ -59,7 +59,7 @@ LL + } | error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:67:5 + --> $DIR/match_single_binding.rs:68:5 | LL | / match a { LL | | _ => { @@ -81,7 +81,7 @@ LL + } | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:77:5 + --> $DIR/match_single_binding.rs:78:5 | LL | / match p { LL | | Point { x, y } => println!("Coords: ({}, {})", x, y), @@ -95,7 +95,7 @@ LL + println!("Coords: ({}, {})", x, y); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:81:5 + --> $DIR/match_single_binding.rs:82:5 | LL | / match p { LL | | Point { x: x1, y: y1 } => println!("Coords: ({}, {})", x1, y1), @@ -109,7 +109,7 @@ LL + println!("Coords: ({}, {})", x1, y1); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:86:5 + --> $DIR/match_single_binding.rs:87:5 | LL | / match x { LL | | ref r => println!("Got a reference to {}", r), @@ -123,7 +123,7 @@ LL + println!("Got a reference to {}", r); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:91:5 + --> $DIR/match_single_binding.rs:92:5 | LL | / match x { LL | | ref mut mr => println!("Got a mutable reference to {}", mr), @@ -137,7 +137,7 @@ LL + println!("Got a mutable reference to {}", mr); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:95:5 + --> $DIR/match_single_binding.rs:96:5 | LL | / let product = match coords() { LL | | Point { x, y } => x * y, @@ -151,7 +151,7 @@ LL + let product = x * y; | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:103:18 + --> $DIR/match_single_binding.rs:104:18 | LL | .map(|i| match i.unwrap() { | __________________^ @@ -168,7 +168,7 @@ LL ~ }) | error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:129:5 + --> $DIR/match_single_binding.rs:130:5 | LL | / match x { LL | | // => @@ -177,7 +177,7 @@ LL | | } | |_____^ help: consider using the match body instead: `println!("Not an array index start")` error: this assignment could be simplified - --> $DIR/match_single_binding.rs:138:5 + --> $DIR/match_single_binding.rs:139:5 | LL | / val = match val.split_at(idx) { LL | | (pre, suf) => { @@ -197,7 +197,7 @@ LL ~ }; | error: this match could be replaced by its scrutinee and body - --> $DIR/match_single_binding.rs:151:16 + --> $DIR/match_single_binding.rs:152:16 | LL | let _ = || match side_effects() { | ________________^ @@ -214,7 +214,7 @@ LL ~ }; | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:157:5 + --> $DIR/match_single_binding.rs:158:5 | LL | / match r { LL | | x => match x { @@ -239,7 +239,7 @@ LL ~ }; | error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:170:5 + --> $DIR/match_single_binding.rs:171:5 | LL | / match 1 { LL | | _ => (), @@ -247,7 +247,7 @@ LL | | } | |_____^ help: consider using the match body instead: `();` error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:174:13 + --> $DIR/match_single_binding.rs:175:13 | LL | let a = match 1 { | _____________^ @@ -256,7 +256,7 @@ LL | | }; | |_____^ help: consider using the match body instead: `()` error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:178:5 + --> $DIR/match_single_binding.rs:179:5 | LL | / match 1 { LL | | _ => side_effects(), @@ -264,7 +264,7 @@ LL | | } | |_____^ help: consider using the match body instead: `side_effects();` error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:182:13 + --> $DIR/match_single_binding.rs:183:13 | LL | let b = match 1 { | _____________^ @@ -273,7 +273,7 @@ LL | | }; | |_____^ help: consider using the match body instead: `side_effects()` error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:186:5 + --> $DIR/match_single_binding.rs:187:5 | LL | / match 1 { LL | | _ => println!("1"), @@ -281,7 +281,7 @@ LL | | } | |_____^ help: consider using the match body instead: `println!("1");` error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:190:13 + --> $DIR/match_single_binding.rs:191:13 | LL | let c = match 1 { | _____________^ @@ -290,7 +290,7 @@ LL | | }; | |_____^ help: consider using the match body instead: `println!("1")` error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:195:9 + --> $DIR/match_single_binding.rs:196:9 | LL | / match 1 { LL | | _ => (), @@ -298,7 +298,7 @@ LL | | }, | |_________^ help: consider using the match body instead: `()` error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:198:9 + --> $DIR/match_single_binding.rs:199:9 | LL | / match 1 { LL | | _ => side_effects(), @@ -306,7 +306,7 @@ LL | | }, | |_________^ help: consider using the match body instead: `side_effects()` error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:201:9 + --> $DIR/match_single_binding.rs:202:9 | LL | / match 1 { LL | | _ => println!("1"), diff --git a/tests/ui/match_single_binding2.fixed b/tests/ui/match_single_binding2.fixed index e3cf56a4293c..adfb4ba91f74 100644 --- a/tests/ui/match_single_binding2.fixed +++ b/tests/ui/match_single_binding2.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_single_binding)] #![allow(unused_variables)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/match_single_binding2.rs b/tests/ui/match_single_binding2.rs index 5a4bb8441fff..b5cfe3654a58 100644 --- a/tests/ui/match_single_binding2.rs +++ b/tests/ui/match_single_binding2.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_single_binding)] #![allow(unused_variables)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/match_str_case_mismatch.fixed b/tests/ui/match_str_case_mismatch.fixed index e436bcf495fd..cd53b1f06faa 100644 --- a/tests/ui/match_str_case_mismatch.fixed +++ b/tests/ui/match_str_case_mismatch.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_str_case_mismatch)] #![allow(dead_code)] diff --git a/tests/ui/match_str_case_mismatch.rs b/tests/ui/match_str_case_mismatch.rs index 92e2a000ade2..6885305662a2 100644 --- a/tests/ui/match_str_case_mismatch.rs +++ b/tests/ui/match_str_case_mismatch.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_str_case_mismatch)] #![allow(dead_code)] diff --git a/tests/ui/match_wild_err_arm.rs b/tests/ui/match_wild_err_arm.rs index 823be65efe06..5a552e4ae51a 100644 --- a/tests/ui/match_wild_err_arm.rs +++ b/tests/ui/match_wild_err_arm.rs @@ -1,7 +1,20 @@ #![feature(exclusive_range_pattern)] -#![allow(clippy::match_same_arms)] +#![allow(clippy::match_same_arms, dead_code)] #![warn(clippy::match_wild_err_arm)] +fn issue_10635() { + enum Error { + A, + B, + } + + // Don't trigger in const contexts. Const unwrap is not yet stable + const X: () = match Ok::<_, Error>(()) { + Ok(x) => x, + Err(_) => panic!(), + }; +} + fn match_wild_err_arm() { let x: Result = Ok(3); diff --git a/tests/ui/match_wild_err_arm.stderr b/tests/ui/match_wild_err_arm.stderr index b016d682698c..a9f54feacdb5 100644 --- a/tests/ui/match_wild_err_arm.stderr +++ b/tests/ui/match_wild_err_arm.stderr @@ -1,5 +1,5 @@ error: `Err(_)` matches all errors - --> $DIR/match_wild_err_arm.rs:11:9 + --> $DIR/match_wild_err_arm.rs:24:9 | LL | Err(_) => panic!("err"), | ^^^^^^ @@ -8,7 +8,7 @@ LL | Err(_) => panic!("err"), = note: `-D clippy::match-wild-err-arm` implied by `-D warnings` error: `Err(_)` matches all errors - --> $DIR/match_wild_err_arm.rs:17:9 + --> $DIR/match_wild_err_arm.rs:30:9 | LL | Err(_) => panic!(), | ^^^^^^ @@ -16,7 +16,7 @@ LL | Err(_) => panic!(), = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_)` matches all errors - --> $DIR/match_wild_err_arm.rs:23:9 + --> $DIR/match_wild_err_arm.rs:36:9 | LL | Err(_) => { | ^^^^^^ @@ -24,7 +24,7 @@ LL | Err(_) => { = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable error: `Err(_e)` matches all errors - --> $DIR/match_wild_err_arm.rs:31:9 + --> $DIR/match_wild_err_arm.rs:44:9 | LL | Err(_e) => panic!(), | ^^^^^^^ diff --git a/tests/ui/match_wildcard_for_single_variants.fixed b/tests/ui/match_wildcard_for_single_variants.fixed index 9fd3739b69c2..d2e6fef07594 100644 --- a/tests/ui/match_wildcard_for_single_variants.fixed +++ b/tests/ui/match_wildcard_for_single_variants.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_wildcard_for_single_variants)] #![allow(dead_code)] diff --git a/tests/ui/match_wildcard_for_single_variants.rs b/tests/ui/match_wildcard_for_single_variants.rs index 9a5c849e6ec9..cff0c8960650 100644 --- a/tests/ui/match_wildcard_for_single_variants.rs +++ b/tests/ui/match_wildcard_for_single_variants.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_wildcard_for_single_variants)] #![allow(dead_code)] diff --git a/tests/ui/match_wildcard_for_single_variants.stderr b/tests/ui/match_wildcard_for_single_variants.stderr index 105b4c4b41d1..40ff4fbd3160 100644 --- a/tests/ui/match_wildcard_for_single_variants.stderr +++ b/tests/ui/match_wildcard_for_single_variants.stderr @@ -2,7 +2,7 @@ error: wildcard matches only a single variant and will also match any future add --> $DIR/match_wildcard_for_single_variants.rs:24:13 | LL | _ => (), - | ^ help: try this: `Self::Rgb(..)` + | ^ help: try: `Self::Rgb(..)` | = note: `-D clippy::match-wildcard-for-single-variants` implied by `-D warnings` @@ -10,55 +10,55 @@ error: wildcard matches only a single variant and will also match any future add --> $DIR/match_wildcard_for_single_variants.rs:34:9 | LL | _ => {}, - | ^ help: try this: `Foo::C` + | ^ help: try: `Foo::C` error: wildcard matches only a single variant and will also match any future added variants --> $DIR/match_wildcard_for_single_variants.rs:44:9 | LL | _ => {}, - | ^ help: try this: `Color::Blue` + | ^ help: try: `Color::Blue` error: wildcard matches only a single variant and will also match any future added variants --> $DIR/match_wildcard_for_single_variants.rs:52:9 | LL | _ => {}, - | ^ help: try this: `Color::Blue` + | ^ help: try: `Color::Blue` error: wildcard matches only a single variant and will also match any future added variants --> $DIR/match_wildcard_for_single_variants.rs:58:9 | LL | _ => {}, - | ^ help: try this: `Color::Blue` + | ^ help: try: `Color::Blue` error: wildcard matches only a single variant and will also match any future added variants --> $DIR/match_wildcard_for_single_variants.rs:75:9 | LL | &_ => (), - | ^^ help: try this: `Color::Blue` + | ^^ help: try: `Color::Blue` error: wildcard matches only a single variant and will also match any future added variants --> $DIR/match_wildcard_for_single_variants.rs:84:9 | LL | _ => (), - | ^ help: try this: `C::Blue` + | ^ help: try: `C::Blue` error: wildcard matches only a single variant and will also match any future added variants --> $DIR/match_wildcard_for_single_variants.rs:91:9 | LL | _ => (), - | ^ help: try this: `Color::Blue` + | ^ help: try: `Color::Blue` error: wildcard matches only a single variant and will also match any future added variants --> $DIR/match_wildcard_for_single_variants.rs:126:13 | LL | _ => (), - | ^ help: try this: `Enum::__Private` + | ^ help: try: `Enum::__Private` error: wildcard matches only a single variant and will also match any future added variants --> $DIR/match_wildcard_for_single_variants.rs:153:13 | LL | _ => 2, - | ^ help: try this: `Foo::B` + | ^ help: try: `Foo::B` error: aborting due to 10 previous errors diff --git a/tests/ui/mem_forget.rs b/tests/ui/mem_forget.rs index e5b35c098a23..b6c8d9e53d80 100644 --- a/tests/ui/mem_forget.rs +++ b/tests/ui/mem_forget.rs @@ -5,7 +5,7 @@ use std::mem as memstuff; use std::mem::forget as forgetSomething; #[warn(clippy::mem_forget)] -#[allow(clippy::forget_copy)] +#[allow(forgetting_copy_types)] fn main() { let five: i32 = 5; forgetSomething(five); @@ -19,5 +19,8 @@ fn main() { let eight: Vec = vec![8]; forgetSomething(eight); + let string = String::new(); + std::mem::forget(string); + std::mem::forget(7); } diff --git a/tests/ui/mem_forget.stderr b/tests/ui/mem_forget.stderr index a90d8b1655dc..65fe5b9c7914 100644 --- a/tests/ui/mem_forget.stderr +++ b/tests/ui/mem_forget.stderr @@ -4,6 +4,19 @@ error: usage of `mem::forget` on `Drop` type LL | memstuff::forget(six); | ^^^^^^^^^^^^^^^^^^^^^ | +<<<<<<< HEAD +<<<<<<< HEAD + = note: argument has type `std::sync::Arc` +======= +note: argument has type `std::sync::Arc` + --> $DIR/mem_forget.rs:14:22 + | +LL | memstuff::forget(six); + | ^^^ +>>>>>>> b6f194b48 (move to `drop_forget_ref`) +======= + = note: argument has type `std::sync::Arc` +>>>>>>> a5ae9044f (make note less verbose) = note: `-D clippy::mem-forget` implied by `-D warnings` error: usage of `mem::forget` on `Drop` type @@ -11,12 +24,64 @@ error: usage of `mem::forget` on `Drop` type | LL | std::mem::forget(seven); | ^^^^^^^^^^^^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD + = note: argument has type `std::rc::Rc` +======= +note: argument has type `std::rc::Rc` + --> $DIR/mem_forget.rs:17:22 + | +LL | std::mem::forget(seven); + | ^^^^^ +>>>>>>> b6f194b48 (move to `drop_forget_ref`) +======= + = note: argument has type `std::rc::Rc` +>>>>>>> a5ae9044f (make note less verbose) error: usage of `mem::forget` on `Drop` type --> $DIR/mem_forget.rs:20:5 | LL | forgetSomething(eight); | ^^^^^^^^^^^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD + = note: argument has type `std::vec::Vec` +======= +note: argument has type `std::vec::Vec` + --> $DIR/mem_forget.rs:20:21 + | +LL | forgetSomething(eight); + | ^^^^^ +>>>>>>> b6f194b48 (move to `drop_forget_ref`) +======= + = note: argument has type `std::vec::Vec` +>>>>>>> a5ae9044f (make note less verbose) + +error: usage of `mem::forget` on type with `Drop` fields + --> $DIR/mem_forget.rs:23:5 + | +LL | std::mem::forget(string); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +<<<<<<< HEAD +<<<<<<< HEAD + | + = note: argument has type `std::string::String` +======= +>>>>>>> d8d59965f (Lint `mem_forget` if fields are `Drop`) +======= + | +<<<<<<< HEAD +note: argument has type `std::string::String` + --> $DIR/mem_forget.rs:23:22 + | +LL | std::mem::forget(string); + | ^^^^^^ +>>>>>>> b6f194b48 (move to `drop_forget_ref`) +======= + = note: argument has type `std::string::String` +>>>>>>> a5ae9044f (make note less verbose) -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/mem_replace.fixed b/tests/ui/mem_replace.fixed index 7fd340173af9..d37e97b0a060 100644 --- a/tests/ui/mem_replace.fixed +++ b/tests/ui/mem_replace.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn( diff --git a/tests/ui/mem_replace.rs b/tests/ui/mem_replace.rs index fa2903addbc0..34e37f3dbbbd 100644 --- a/tests/ui/mem_replace.rs +++ b/tests/ui/mem_replace.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn( diff --git a/tests/ui/mem_replace_macro.rs b/tests/ui/mem_replace_macro.rs index 3932e7d00c19..aae073a09690 100644 --- a/tests/ui/mem_replace_macro.rs +++ b/tests/ui/mem_replace_macro.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::mem_replace_with_default)] extern crate proc_macros; diff --git a/tests/ui/methods.rs b/tests/ui/methods.rs index 1519e4da9348..cb1f695c651c 100644 --- a/tests/ui/methods.rs +++ b/tests/ui/methods.rs @@ -1,4 +1,4 @@ -// aux-build:option_helpers.rs +//@aux-build:option_helpers.rs #![warn(clippy::all, clippy::pedantic)] #![allow( @@ -18,16 +18,14 @@ clippy::wrong_self_convention, clippy::unused_async, clippy::unused_self, + clippy::useless_vec, unused )] #[macro_use] extern crate option_helpers; -use std::collections::BTreeMap; -use std::collections::HashMap; -use std::collections::HashSet; -use std::collections::VecDeque; +use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::ops::Mul; use std::rc::{self, Rc}; use std::sync::{self, Arc}; diff --git a/tests/ui/methods.stderr b/tests/ui/methods.stderr index 4643e09e2702..6be38b24fbda 100644 --- a/tests/ui/methods.stderr +++ b/tests/ui/methods.stderr @@ -1,5 +1,5 @@ error: methods called `new` usually return `Self` - --> $DIR/methods.rs:105:5 + --> $DIR/methods.rs:103:5 | LL | / fn new() -> i32 { LL | | 0 @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::new-ret-no-self` implied by `-D warnings` error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead - --> $DIR/methods.rs:126:13 + --> $DIR/methods.rs:124:13 | LL | let _ = v.iter().filter(|&x| { | _____________^ diff --git a/tests/ui/methods_fixable.fixed b/tests/ui/methods_fixable.fixed index ee7c1b0da6d9..ce5d19a8b6e8 100644 --- a/tests/ui/methods_fixable.fixed +++ b/tests/ui/methods_fixable.fixed @@ -1,6 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::filter_next)] +#![allow(clippy::useless_vec)] /// Checks implementation of `FILTER_NEXT` lint. fn main() { diff --git a/tests/ui/methods_fixable.rs b/tests/ui/methods_fixable.rs index 6d0f1b7bd514..0615817ec925 100644 --- a/tests/ui/methods_fixable.rs +++ b/tests/ui/methods_fixable.rs @@ -1,6 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::filter_next)] +#![allow(clippy::useless_vec)] /// Checks implementation of `FILTER_NEXT` lint. fn main() { diff --git a/tests/ui/methods_fixable.stderr b/tests/ui/methods_fixable.stderr index 852f48e32d67..6f45d100d282 100644 --- a/tests/ui/methods_fixable.stderr +++ b/tests/ui/methods_fixable.stderr @@ -1,8 +1,8 @@ error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead - --> $DIR/methods_fixable.rs:10:13 + --> $DIR/methods_fixable.rs:11:13 | LL | let _ = v.iter().filter(|&x| *x < 0).next(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `v.iter().find(|&x| *x < 0)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.iter().find(|&x| *x < 0)` | = note: `-D clippy::filter-next` implied by `-D warnings` diff --git a/tests/ui/methods_unfixable.rs b/tests/ui/methods_unfixable.rs new file mode 100644 index 000000000000..3d88ce4b6bbd --- /dev/null +++ b/tests/ui/methods_unfixable.rs @@ -0,0 +1,10 @@ +#![warn(clippy::filter_next)] + +fn main() { + issue10029(); +} + +pub fn issue10029() { + let iter = (0..10); + let _ = iter.filter(|_| true).next(); +} diff --git a/tests/ui/methods_unfixable.stderr b/tests/ui/methods_unfixable.stderr new file mode 100644 index 000000000000..6e101fe16b09 --- /dev/null +++ b/tests/ui/methods_unfixable.stderr @@ -0,0 +1,15 @@ +error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead + --> $DIR/methods_unfixable.rs:9:13 + | +LL | let _ = iter.filter(|_| true).next(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `iter.find(|_| true)` + | +help: you will also need to make `iter` mutable, because `find` takes `&mut self` + --> $DIR/methods_unfixable.rs:8:9 + | +LL | let iter = (0..10); + | ^^^^ + = note: `-D clippy::filter-next` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/tests/ui/min_ident_chars.rs b/tests/ui/min_ident_chars.rs new file mode 100644 index 000000000000..4f3ef34e8887 --- /dev/null +++ b/tests/ui/min_ident_chars.rs @@ -0,0 +1,133 @@ +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5bd97ac17 (Update tests) +//@aux-build:proc_macros.rs:proc-macro +#![allow(irrefutable_let_patterns, nonstandard_style, unused)] +======= +//@aux-build:proc_macros.rs +<<<<<<< HEAD +#![allow(nonstandard_style, unused)] +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +#![allow(irrefutable_let_patterns, nonstandard_style, unused)] +>>>>>>> 243943ff5 (make it work for locals as well) +#![warn(clippy::min_ident_chars)] + +extern crate proc_macros; +use proc_macros::{external, with_span}; + +struct A { + a: u32, + i: u32, + A: u32, + I: u32, +} + +struct B(u32); + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 243943ff5 (make it work for locals as well) +struct O { + o: u32, +} + +<<<<<<< HEAD +======= +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +>>>>>>> 243943ff5 (make it work for locals as well) +struct i; + +enum C { + D, + E, + F, + j, +} + +struct Vec4 { + x: u32, + y: u32, + z: u32, + w: u32, +} + +struct AA(T, E); + +fn main() { + // Allowed idents + let w = 1; + // Ok, not this one + // let i = 1; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 243943ff5 (make it work for locals as well) + let j = 1; + let n = 1; + let z = 1; + let y = 1; + let z = 1; + // Implicitly disallowed idents + let h = 1; + let e = 2; + let l = 3; + let l = 4; + let o = 6; + // 2 len does not lint + let hi = 0; + // Lint + let (h, o, w) = (1, 2, 3); + for (a, (r, e)) in (0..1000).enumerate().enumerate() {} + let you = Vec4 { x: 1, y: 2, z: 3, w: 4 }; + while let (d, o, _i, n, g) = (true, true, false, false, true) {} + let today = true; + // Ideally this wouldn't lint, but this would (likely) require global analysis, outta scope + // of this lint regardless + let o = 1; + let o = O { o }; +<<<<<<< HEAD + + for j in 0..1000 {} + for _ in 0..10 {} +<<<<<<< HEAD +======= + let jz = 1; + let nz = 1; + let zx = 1; + let yz = 1; + let zz = 1; +======= +>>>>>>> 243943ff5 (make it work for locals as well) + + for j in 0..1000 {} +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +>>>>>>> 95d1bff22 (add to tests and configuration) + + // Do not lint code from external macros + external! { for j in 0..1000 {} } + // Do not lint code from procedural macros + with_span! { + span + for j in 0..1000 {} + } +} + +fn b() {} +<<<<<<< HEAD +<<<<<<< HEAD +fn wrong_pythagoras(a: f32, b: f32) -> f32 { + a * a + a * b +} +======= +fn owo() {} +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +fn wrong_pythagoras(a: f32, b: f32) -> f32 { + a * a + a * b +} +>>>>>>> 95d1bff22 (add to tests and configuration) diff --git a/tests/ui/min_ident_chars.stderr b/tests/ui/min_ident_chars.stderr new file mode 100644 index 000000000000..af461eb3e538 --- /dev/null +++ b/tests/ui/min_ident_chars.stderr @@ -0,0 +1,359 @@ +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:8:8 + | +LL | struct A { + | ^ + | + = note: `-D clippy::min-ident-chars` implied by `-D warnings` + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:9:5 + | +LL | a: u32, + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:11:5 + | +LL | A: u32, + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:12:5 + | +LL | I: u32, + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:15:8 + | +LL | struct B(u32); + | ^ + +error: this ident consists of a single char +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 243943ff5 (make it work for locals as well) + --> $DIR/min_ident_chars.rs:18:8 +======= + --> $DIR/min_ident_chars.rs:17:8 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) + | +LL | struct O { + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:18:5 + | +LL | o: u32, + | ^ + +error: this ident consists of a single char +<<<<<<< HEAD + --> $DIR/min_ident_chars.rs:24:6 +<<<<<<< HEAD +======= + --> $DIR/min_ident_chars.rs:20:6 +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +>>>>>>> 243943ff5 (make it work for locals as well) +======= + --> $DIR/min_ident_chars.rs:23:6 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) + | +LL | enum C { + | ^ + +error: this ident consists of a single char +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/min_ident_chars.rs:25:5 +======= + --> $DIR/min_ident_chars.rs:21:5 +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + --> $DIR/min_ident_chars.rs:25:5 +>>>>>>> 243943ff5 (make it work for locals as well) +======= + --> $DIR/min_ident_chars.rs:24:5 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) + | +LL | D, + | ^ + +error: this ident consists of a single char +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/min_ident_chars.rs:26:5 +======= + --> $DIR/min_ident_chars.rs:22:5 +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + --> $DIR/min_ident_chars.rs:26:5 +>>>>>>> 243943ff5 (make it work for locals as well) +======= + --> $DIR/min_ident_chars.rs:25:5 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) + | +LL | E, + | ^ + +error: this ident consists of a single char +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/min_ident_chars.rs:27:5 +======= + --> $DIR/min_ident_chars.rs:23:5 +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + --> $DIR/min_ident_chars.rs:27:5 +>>>>>>> 243943ff5 (make it work for locals as well) +======= + --> $DIR/min_ident_chars.rs:26:5 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) + | +LL | F, + | ^ + +error: this ident consists of a single char +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/min_ident_chars.rs:51:9 +======= + --> $DIR/min_ident_chars.rs:50:9 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) + | +LL | let h = 1; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:51:9 + | +LL | let e = 2; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:52:9 + | +LL | let l = 3; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:53:9 + | +LL | let l = 4; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:54:9 + | +LL | let o = 6; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:58:10 + | +LL | let (h, o, w) = (1, 2, 3); + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:58:13 + | +LL | let (h, o, w) = (1, 2, 3); + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:59:10 + | +LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:59:14 + | +LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:59:17 + | +LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:61:16 + | +LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:61:19 + | +LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:61:29 + | +LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:65:9 + | +LL | let o = 1; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:66:9 + | +LL | let o = O { o }; + | ^ + +error: this ident consists of a single char +<<<<<<< HEAD + --> $DIR/min_ident_chars.rs:81:4 +<<<<<<< HEAD +======= + --> $DIR/min_ident_chars.rs:31:5 +======= + --> $DIR/min_ident_chars.rs:51:9 +>>>>>>> 243943ff5 (make it work for locals as well) + | +LL | let h = 1; + | ^ + +error: this ident consists of a single char +<<<<<<< HEAD + --> $DIR/min_ident_chars.rs:58:4 +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= + --> $DIR/min_ident_chars.rs:52:9 + | +LL | let e = 2; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:53:9 + | +LL | let l = 3; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:54:9 + | +LL | let l = 4; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:55:9 + | +LL | let o = 6; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:59:10 + | +LL | let (h, o, w) = (1, 2, 3); + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:59:13 + | +LL | let (h, o, w) = (1, 2, 3); + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:60:10 + | +LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:60:14 + | +LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:60:17 + | +LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:62:16 + | +LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:62:19 + | +LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:62:29 + | +LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {} + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:66:9 + | +LL | let o = 1; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:67:9 + | +LL | let o = O { o }; + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:80:4 +>>>>>>> 243943ff5 (make it work for locals as well) +======= +>>>>>>> 95d1bff22 (add to tests and configuration) +======= + --> $DIR/min_ident_chars.rs:80:4 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) + | +LL | fn b() {} + | ^ + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 95d1bff22 (add to tests and configuration) +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:81:21 + | +LL | fn wrong_pythagoras(a: f32, b: f32) -> f32 { + | ^ + +error: this ident consists of a single char + --> $DIR/min_ident_chars.rs:81:29 + | +LL | fn wrong_pythagoras(a: f32, b: f32) -> f32 { + | ^ + +error: aborting due to 29 previous errors +<<<<<<< HEAD +======= +error: aborting due to 11 previous errors +>>>>>>> 7cdd87ca4 (ignore generics and allow arbitrary threshold) +======= +error: aborting due to 27 previous errors +>>>>>>> 243943ff5 (make it work for locals as well) +======= +>>>>>>> 95d1bff22 (add to tests and configuration) + diff --git a/tests/ui/min_max.rs b/tests/ui/min_max.rs index 24e52afd6917..1215a02286c2 100644 --- a/tests/ui/min_max.rs +++ b/tests/ui/min_max.rs @@ -1,9 +1,7 @@ #![warn(clippy::all)] #![allow(clippy::manual_clamp)] -use std::cmp::max as my_max; -use std::cmp::min as my_min; -use std::cmp::{max, min}; +use std::cmp::{max as my_max, max, min as my_min, min}; const LARGE: usize = 3; diff --git a/tests/ui/min_max.stderr b/tests/ui/min_max.stderr index 069d9068657e..402b094f4f77 100644 --- a/tests/ui/min_max.stderr +++ b/tests/ui/min_max.stderr @@ -1,5 +1,5 @@ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:24:5 + --> $DIR/min_max.rs:22:5 | LL | min(1, max(3, x)); | ^^^^^^^^^^^^^^^^^ @@ -7,73 +7,73 @@ LL | min(1, max(3, x)); = note: `-D clippy::min-max` implied by `-D warnings` error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:25:5 + --> $DIR/min_max.rs:23:5 | LL | min(max(3, x), 1); | ^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:26:5 + --> $DIR/min_max.rs:24:5 | LL | max(min(x, 1), 3); | ^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:27:5 + --> $DIR/min_max.rs:25:5 | LL | max(3, min(x, 1)); | ^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:29:5 + --> $DIR/min_max.rs:27:5 | LL | my_max(3, my_min(x, 1)); | ^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:39:5 + --> $DIR/min_max.rs:37:5 | LL | min("Apple", max("Zoo", s)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:40:5 + --> $DIR/min_max.rs:38:5 | LL | max(min(s, "Apple"), "Zoo"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:45:5 + --> $DIR/min_max.rs:43:5 | LL | x.min(1).max(3); | ^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:46:5 + --> $DIR/min_max.rs:44:5 | LL | x.max(3).min(1); | ^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:47:5 + --> $DIR/min_max.rs:45:5 | LL | f.max(3f32).min(1f32); | ^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:53:5 + --> $DIR/min_max.rs:51:5 | LL | max(x.min(1), 3); | ^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:56:5 + --> $DIR/min_max.rs:54:5 | LL | s.max("Zoo").min("Apple"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `min`/`max` combination leads to constant result - --> $DIR/min_max.rs:57:5 + --> $DIR/min_max.rs:55:5 | LL | s.min("Apple").max("Zoo"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/mismatched_target_os_non_unix.fixed b/tests/ui/mismatched_target_os_non_unix.fixed index f219a570e7fc..f58e9a429b62 100644 --- a/tests/ui/mismatched_target_os_non_unix.fixed +++ b/tests/ui/mismatched_target_os_non_unix.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::mismatched_target_os)] #![allow(unused)] diff --git a/tests/ui/mismatched_target_os_non_unix.rs b/tests/ui/mismatched_target_os_non_unix.rs index 8a8ae756a4fc..e00224f5ceb4 100644 --- a/tests/ui/mismatched_target_os_non_unix.rs +++ b/tests/ui/mismatched_target_os_non_unix.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::mismatched_target_os)] #![allow(unused)] diff --git a/tests/ui/mismatched_target_os_unix.fixed b/tests/ui/mismatched_target_os_unix.fixed index 7d9d406d99df..330587a3c4c3 100644 --- a/tests/ui/mismatched_target_os_unix.fixed +++ b/tests/ui/mismatched_target_os_unix.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::mismatched_target_os)] #![allow(unused)] diff --git a/tests/ui/mismatched_target_os_unix.rs b/tests/ui/mismatched_target_os_unix.rs index c1177f1eedc6..5a90019a2e4c 100644 --- a/tests/ui/mismatched_target_os_unix.rs +++ b/tests/ui/mismatched_target_os_unix.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::mismatched_target_os)] #![allow(unused)] diff --git a/tests/ui/missing_assert_message.rs b/tests/ui/missing_assert_message.rs index 89404ca88271..af1358f61b5c 100644 --- a/tests/ui/missing_assert_message.rs +++ b/tests/ui/missing_assert_message.rs @@ -7,8 +7,6 @@ macro_rules! bar { }; } -fn main() {} - // Should trigger warning fn asserts_without_message() { assert!(foo()); @@ -66,9 +64,14 @@ fn asserts_without_message_but_inside_a_test_function() { debug_assert_ne!(foo(), foo()); } +fn foo() -> bool { + true +} + // Should not trigger warning #[cfg(test)] mod tests { + use super::foo; fn asserts_without_message_but_inside_a_test_module() { assert!(foo()); assert_eq!(foo(), foo()); @@ -78,7 +81,3 @@ mod tests { debug_assert_ne!(foo(), foo()); } } - -fn foo() -> bool { - true -} diff --git a/tests/ui/missing_assert_message.stderr b/tests/ui/missing_assert_message.stderr index ecd038012779..33a5c1f8e052 100644 --- a/tests/ui/missing_assert_message.stderr +++ b/tests/ui/missing_assert_message.stderr @@ -1,5 +1,5 @@ error: assert without any message - --> $DIR/missing_assert_message.rs:14:5 + --> $DIR/missing_assert_message.rs:12:5 | LL | assert!(foo()); | ^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | assert!(foo()); = note: `-D clippy::missing-assert-message` implied by `-D warnings` error: assert without any message - --> $DIR/missing_assert_message.rs:15:5 + --> $DIR/missing_assert_message.rs:13:5 | LL | assert_eq!(foo(), foo()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | assert_eq!(foo(), foo()); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:16:5 + --> $DIR/missing_assert_message.rs:14:5 | LL | assert_ne!(foo(), foo()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | assert_ne!(foo(), foo()); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:17:5 + --> $DIR/missing_assert_message.rs:15:5 | LL | debug_assert!(foo()); | ^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | debug_assert!(foo()); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:18:5 + --> $DIR/missing_assert_message.rs:16:5 | LL | debug_assert_eq!(foo(), foo()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | debug_assert_eq!(foo(), foo()); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:19:5 + --> $DIR/missing_assert_message.rs:17:5 | LL | debug_assert_ne!(foo(), foo()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | debug_assert_ne!(foo(), foo()); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:24:5 + --> $DIR/missing_assert_message.rs:22:5 | LL | assert!(bar!(true)); | ^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | assert!(bar!(true)); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:25:5 + --> $DIR/missing_assert_message.rs:23:5 | LL | assert!(bar!(true, false)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | assert!(bar!(true, false)); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:26:5 + --> $DIR/missing_assert_message.rs:24:5 | LL | assert_eq!(bar!(true), foo()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | assert_eq!(bar!(true), foo()); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:27:5 + --> $DIR/missing_assert_message.rs:25:5 | LL | assert_ne!(bar!(true, true), bar!(true)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | assert_ne!(bar!(true, true), bar!(true)); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:32:5 + --> $DIR/missing_assert_message.rs:30:5 | LL | assert!(foo(),); | ^^^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ LL | assert!(foo(),); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:33:5 + --> $DIR/missing_assert_message.rs:31:5 | LL | assert_eq!(foo(), foo(),); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL | assert_eq!(foo(), foo(),); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:34:5 + --> $DIR/missing_assert_message.rs:32:5 | LL | assert_ne!(foo(), foo(),); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +104,7 @@ LL | assert_ne!(foo(), foo(),); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:35:5 + --> $DIR/missing_assert_message.rs:33:5 | LL | debug_assert!(foo(),); | ^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +112,7 @@ LL | debug_assert!(foo(),); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:36:5 + --> $DIR/missing_assert_message.rs:34:5 | LL | debug_assert_eq!(foo(), foo(),); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -120,7 +120,7 @@ LL | debug_assert_eq!(foo(), foo(),); = help: consider describing why the failing assert is problematic error: assert without any message - --> $DIR/missing_assert_message.rs:37:5 + --> $DIR/missing_assert_message.rs:35:5 | LL | debug_assert_ne!(foo(), foo(),); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/missing_const_for_fn/cant_be_const.rs b/tests/ui/missing_const_for_fn/cant_be_const.rs index e6f88c6e622c..2ad28ed4b8eb 100644 --- a/tests/ui/missing_const_for_fn/cant_be_const.rs +++ b/tests/ui/missing_const_for_fn/cant_be_const.rs @@ -2,8 +2,12 @@ //! compilation error. //! The .stderr output of this test should be empty. Otherwise it's a bug somewhere. -// aux-build:helper.rs -// aux-build:../../auxiliary/proc_macros.rs +//@aux-build:helper.rs +<<<<<<< HEAD +//@aux-build:../auxiliary/proc_macros.rs:proc-macro +======= +//@aux-build:../../auxiliary/proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::missing_const_for_fn)] #![feature(start)] @@ -13,7 +17,7 @@ extern crate proc_macros; use proc_macros::with_span; -struct Game; +struct Game; // You just lost. // This should not be linted because it's already const const fn already_const() -> i32 { @@ -44,7 +48,6 @@ static Y: u32 = 0; // refer to a static variable fn get_y() -> u32 { Y - //~^ ERROR E0013 } // Don't lint entrypoint functions @@ -126,3 +129,73 @@ with_span! { span fn dont_check_in_proc_macro() {} } + +<<<<<<< HEAD +<<<<<<< HEAD +// Do not lint `String` has `Vec`, which cannot be dropped in const contexts +======= +>>>>>>> e24fc9af2 (Fix `missing_const_for_fn` not checking `~const Destruct`) +======= +// Do not lint `String` has `Vec`, which cannot be dropped in const contexts +>>>>>>> 5692677b3 (cleanup spaghetti code) +fn a(this: String) {} + +enum A { + F(String), + N, +} + +<<<<<<< HEAD +<<<<<<< HEAD +// Same here. +fn b(this: A) {} + +<<<<<<< HEAD +======= +// Same here. +fn b(this: A) {} + +>>>>>>> 5692677b3 (cleanup spaghetti code) +// Minimized version of `a`. +fn c(this: Vec) {} + +struct F(A); + +// Do not lint +fn f(this: F) {} + +// Do not lint +fn g(this: T) {} + +struct Issue10617(String); + +impl Issue10617 { + // Do not lint + pub fn name(self) -> String { + self.0 + } +} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 9bc6e114e (add non-test-case for suggesting const on functions accessing union fields) + +union U { + f: u32, +} + +// Do not lint because accessing union fields from const functions is unstable +fn h(u: U) -> u32 { + unsafe { u.f } +} +<<<<<<< HEAD +======= +fn b(this: A) {} +>>>>>>> e24fc9af2 (Fix `missing_const_for_fn` not checking `~const Destruct`) +======= +fn c(this: Vec) {} +>>>>>>> 0e233492d (use trait solver instead; created spaghetti code) +======= +>>>>>>> 5692677b3 (cleanup spaghetti code) +======= +>>>>>>> 9bc6e114e (add non-test-case for suggesting const on functions accessing union fields) diff --git a/tests/ui/missing_const_for_fn/could_be_const.rs b/tests/ui/missing_const_for_fn/could_be_const.rs index 0246c8622ed3..b1980b1b523f 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.rs +++ b/tests/ui/missing_const_for_fn/could_be_const.rs @@ -1,5 +1,7 @@ #![warn(clippy::missing_const_for_fn)] #![allow(incomplete_features, clippy::let_and_return)] +#![feature(const_mut_refs)] +#![feature(const_trait_impl)] use std::mem::transmute; @@ -87,3 +89,14 @@ fn msrv_1_46() -> i32 { // Should not be const fn main() {} + +struct D; + +impl const Drop for D { + fn drop(&mut self) { + todo!(); + } +} + +// Lint this, since it can be dropped in const contexts +fn d(this: D) {} diff --git a/tests/ui/missing_const_for_fn/could_be_const.stderr b/tests/ui/missing_const_for_fn/could_be_const.stderr index 955e1ed26340..7be2cc0ca930 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -1,5 +1,5 @@ error: this could be a `const fn` - --> $DIR/could_be_const.rs:12:5 + --> $DIR/could_be_const.rs:14:5 | LL | / pub fn new() -> Self { LL | | Self { guess: 42 } @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::missing-const-for-fn` implied by `-D warnings` error: this could be a `const fn` - --> $DIR/could_be_const.rs:16:5 + --> $DIR/could_be_const.rs:18:5 | LL | / fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] { LL | | b @@ -17,7 +17,7 @@ LL | | } | |_____^ error: this could be a `const fn` - --> $DIR/could_be_const.rs:22:1 + --> $DIR/could_be_const.rs:24:1 | LL | / fn one() -> i32 { LL | | 1 @@ -25,7 +25,7 @@ LL | | } | |_^ error: this could be a `const fn` - --> $DIR/could_be_const.rs:27:1 + --> $DIR/could_be_const.rs:29:1 | LL | / fn two() -> i32 { LL | | let abc = 2; @@ -34,7 +34,7 @@ LL | | } | |_^ error: this could be a `const fn` - --> $DIR/could_be_const.rs:33:1 + --> $DIR/could_be_const.rs:35:1 | LL | / fn string() -> String { LL | | String::new() @@ -42,7 +42,7 @@ LL | | } | |_^ error: this could be a `const fn` - --> $DIR/could_be_const.rs:38:1 + --> $DIR/could_be_const.rs:40:1 | LL | / unsafe fn four() -> i32 { LL | | 4 @@ -50,7 +50,7 @@ LL | | } | |_^ error: this could be a `const fn` - --> $DIR/could_be_const.rs:43:1 + --> $DIR/could_be_const.rs:45:1 | LL | / fn generic(t: T) -> T { LL | | t @@ -58,7 +58,7 @@ LL | | } | |_^ error: this could be a `const fn` - --> $DIR/could_be_const.rs:51:1 + --> $DIR/could_be_const.rs:53:1 | LL | / fn generic_arr(t: [T; 1]) -> T { LL | | t[0] @@ -66,7 +66,7 @@ LL | | } | |_^ error: this could be a `const fn` - --> $DIR/could_be_const.rs:64:9 + --> $DIR/could_be_const.rs:66:9 | LL | / pub fn b(self, a: &A) -> B { LL | | B @@ -74,7 +74,7 @@ LL | | } | |_________^ error: this could be a `const fn` - --> $DIR/could_be_const.rs:73:5 + --> $DIR/could_be_const.rs:75:5 | LL | / fn const_fn_stabilized_before_msrv(byte: u8) { LL | | byte.is_ascii_digit(); @@ -82,12 +82,18 @@ LL | | } | |_____^ error: this could be a `const fn` - --> $DIR/could_be_const.rs:84:1 + --> $DIR/could_be_const.rs:86:1 | LL | / fn msrv_1_46() -> i32 { LL | | 46 LL | | } | |_^ -error: aborting due to 11 previous errors +error: this could be a `const fn` + --> $DIR/could_be_const.rs:102:1 + | +LL | fn d(this: D) {} + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 12 previous errors diff --git a/tests/ui/missing_doc.rs b/tests/ui/missing_doc.rs index 5752048949ca..7ac91d352f38 100644 --- a/tests/ui/missing_doc.rs +++ b/tests/ui/missing_doc.rs @@ -1,5 +1,9 @@ -// needs-asm-support -// aux-build: proc_macros.rs +//@needs-asm-support +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::missing_docs_in_private_items)] // When denying at the crate level, be sure to not get random warnings from the @@ -96,10 +100,8 @@ mod internal_impl { } /// dox pub mod public_interface { - pub use crate::internal_impl::documented as foo; pub use crate::internal_impl::globbed::*; - pub use crate::internal_impl::undocumented1 as bar; - pub use crate::internal_impl::{documented, undocumented2}; + pub use crate::internal_impl::{documented as foo, documented, undocumented1 as bar, undocumented2}; } fn main() {} diff --git a/tests/ui/missing_doc_impl.rs b/tests/ui/missing_doc_impl.rs index e2d49b0907d5..e82c111ac831 100644 --- a/tests/ui/missing_doc_impl.rs +++ b/tests/ui/missing_doc_impl.rs @@ -1,4 +1,8 @@ -// aux-build: proc_macros.rs +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::missing_docs_in_private_items)] #![allow(dead_code)] diff --git a/tests/ui/missing_fields_in_debug.rs b/tests/ui/missing_fields_in_debug.rs new file mode 100644 index 000000000000..342c8759b25a --- /dev/null +++ b/tests/ui/missing_fields_in_debug.rs @@ -0,0 +1,331 @@ +#![allow(unused)] +#![warn(clippy::missing_fields_in_debug)] + +use std::fmt; +use std::marker::PhantomData; +use std::ops::Deref; + +struct NamedStruct1Ignored { + data: u8, + hidden: u32, +} + +impl fmt::Debug for NamedStruct1Ignored { + // unused field: hidden + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter + .debug_struct("NamedStruct1Ignored") + .field("data", &self.data) + .finish() + } +} + +struct NamedStructMultipleIgnored { + data: u8, + hidden: u32, + hidden2: String, + hidden3: Vec>, + hidden4: ((((u8), u16), u32), u64), +} + +impl fmt::Debug for NamedStructMultipleIgnored { + // unused fields: hidden, hidden2, hidden4 + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter + .debug_struct("NamedStructMultipleIgnored") + .field("data", &self.data) + .field("hidden3", &self.hidden3) + .finish() + } +} + +struct Unit; + +// ok +impl fmt::Debug for Unit { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.debug_struct("Unit").finish() + } +} + +struct UnnamedStruct1Ignored(String); + +impl fmt::Debug for UnnamedStruct1Ignored { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.debug_tuple("UnnamedStruct1Ignored").finish() + } +} + +struct UnnamedStructMultipleIgnored(String, Vec, i32); + +// tuple structs are not linted +impl fmt::Debug for UnnamedStructMultipleIgnored { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter + .debug_tuple("UnnamedStructMultipleIgnored") + .field(&self.1) + .finish() + } +} + +struct NamedStructNonExhaustive { + a: u8, + b: String, +} + +// ok +impl fmt::Debug for NamedStructNonExhaustive { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter + .debug_struct("NamedStructNonExhaustive") + .field("a", &self.a) + .finish_non_exhaustive() // should not warn here + } +} + +struct MultiExprDebugImpl { + a: u8, + b: String, +} + +// ok +impl fmt::Debug for MultiExprDebugImpl { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut f = formatter.debug_struct("MultiExprDebugImpl"); + f.field("a", &self.a); + f.finish() + } +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +enum SingleVariantEnumUnnamed { + A(u8), +} + +// ok +impl fmt::Debug for SingleVariantEnumUnnamed { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::A(n) => formatter.debug_tuple("A").field(&n).finish(), + } + } +} + +enum MultiVariantEnum { + A(u8), + B { a: u8, b: String }, + C, +} + +impl fmt::Debug for MultiVariantEnum { + // match arm Self::B ignores `b` + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::A(n) => formatter.debug_tuple("A").field(&n).finish(), + Self::B { a, b } => formatter.debug_struct("B").field("a", &a).finish(), + Self::C => formatter.debug_struct("C").finish(), + } + } +} + +enum MultiVariantEnumOk { + A(u8), + B { a: u8, b: String }, + C, +} + +// ok +impl fmt::Debug for MultiVariantEnumOk { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::A(n) => formatter.debug_tuple("A").field(&n).finish(), + Self::B { a, b } => formatter.debug_struct("B").field("a", &a).field("b", &b).finish(), + Self::C => formatter.debug_struct("C").finish(), + } + } +} + +enum MultiVariantEnumNonExhaustive { + A(u8), + B { a: u8, b: String }, + C, +} + +// ok +impl fmt::Debug for MultiVariantEnumNonExhaustive { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::A(n) => formatter.debug_tuple("A").field(&n).finish(), + Self::B { a, b } => formatter.debug_struct("B").field("b", &b).finish_non_exhaustive(), + Self::C => formatter.debug_struct("C").finish(), + } + } +} + +enum MultiVariantRest { + A(u8), + B { a: u8, b: String }, + C, +} + +impl fmt::Debug for MultiVariantRest { + // `a` field ignored due to rest pattern + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::A(n) => formatter.debug_tuple("A").field(&n).finish(), + Self::B { b, .. } => formatter.debug_struct("B").field("b", &b).finish(), + Self::C => formatter.debug_struct("C").finish(), + } + } +} + +enum MultiVariantRestNonExhaustive { + A(u8), + B { a: u8, b: String }, + C, +} + +// ok +impl fmt::Debug for MultiVariantRestNonExhaustive { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::A(n) => formatter.debug_tuple("A").field(&n).finish(), + Self::B { b, .. } => formatter.debug_struct("B").field("b", &b).finish_non_exhaustive(), + Self::C => formatter.debug_struct("C").finish(), + } + } +} + +enum Wildcard { + A(u8), + B(String), +} + +// ok +impl fmt::Debug for Wildcard { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::A(n) => formatter.debug_tuple("A").field(&n).finish(), + _ => todo!(), + } + } +} + +enum Empty {} + +// ok +impl fmt::Debug for Empty { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self {} + } +} + +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= +>>>>>>> a859b0e6d (don't lint enums, update note in lint description) +#[derive(Debug)] +struct DerivedStruct { + a: u8, + b: i32, +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +#[derive(Debug)] +enum DerivedEnum { + A(i32), + B { a: String }, +} + +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= +>>>>>>> a859b0e6d (don't lint enums, update note in lint description) +// https://github.com/rust-lang/rust-clippy/pull/10616#discussion_r1166846953 + +struct Inner { + a: usize, + b: usize, +} + +struct HasInner { + inner: Inner, +} + +impl HasInner { + fn get(&self) -> &Inner { + &self.inner + } +} + +impl fmt::Debug for HasInner { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let inner = self.get(); + + f.debug_struct("HasInner") + .field("a", &inner.a) + .field("b", &inner.b) + .finish() + } +} + +// https://github.com/rust-lang/rust-clippy/pull/10616#discussion_r1170306053 +struct Foo { + a: u8, + b: u8, +} + +impl fmt::Debug for Foo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Foo").field("a", &self.a).field("b", &()).finish() + } +} + +// https://github.com/rust-lang/rust-clippy/pull/10616#discussion_r1175473620 +mod comment1175473620 { + use super::*; + + struct Inner { + a: usize, + b: usize, + } + struct Wrapper(Inner); + + impl Deref for Wrapper { + type Target = Inner; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl fmt::Debug for Wrapper { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Wrapper") + .field("a", &self.a) + .field("b", &self.b) + .finish() + } + } +} + +// https://github.com/rust-lang/rust-clippy/pull/10616#discussion_r1175488757 +// PhantomData is an exception and does not need to be included +struct WithPD { + a: u8, + b: u8, + c: PhantomData, +} + +impl fmt::Debug for WithPD { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("WithPD") + .field("a", &self.a) + .field("b", &self.b) + .finish() + } +} + +fn main() {} diff --git a/tests/ui/missing_fields_in_debug.stderr b/tests/ui/missing_fields_in_debug.stderr new file mode 100644 index 000000000000..ef3422311fab --- /dev/null +++ b/tests/ui/missing_fields_in_debug.stderr @@ -0,0 +1,121 @@ +error: manual `Debug` impl does not include all fields + --> $DIR/missing_fields_in_debug.rs:13:1 + | +LL | / impl fmt::Debug for NamedStruct1Ignored { +LL | | // unused field: hidden +LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { +LL | | formatter +... | +LL | | } +LL | | } + | |_^ + | +note: this field is unused + --> $DIR/missing_fields_in_debug.rs:10:5 + | +LL | hidden: u32, + | ^^^^^^^^^^^ + = help: consider including all fields in this `Debug` impl + = help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields + = note: `-D clippy::missing-fields-in-debug` implied by `-D warnings` + +error: manual `Debug` impl does not include all fields + --> $DIR/missing_fields_in_debug.rs:31:1 + | +LL | / impl fmt::Debug for NamedStructMultipleIgnored { +LL | | // unused fields: hidden, hidden2, hidden4 +LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { +LL | | formatter +... | +LL | | } +LL | | } + | |_^ + | +note: this field is unused + --> $DIR/missing_fields_in_debug.rs:25:5 + | +LL | hidden: u32, + | ^^^^^^^^^^^ +note: this field is unused + --> $DIR/missing_fields_in_debug.rs:26:5 + | +LL | hidden2: String, + | ^^^^^^^^^^^^^^^ +note: this field is unused + --> $DIR/missing_fields_in_debug.rs:28:5 + | +LL | hidden4: ((((u8), u16), u32), u64), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider including all fields in this `Debug` impl + = help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields + +error: manual `Debug` impl does not include all fields + --> $DIR/missing_fields_in_debug.rs:92:1 + | +LL | / impl fmt::Debug for MultiExprDebugImpl { +LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { +LL | | let mut f = formatter.debug_struct("MultiExprDebugImpl"); +LL | | f.field("a", &self.a); +LL | | f.finish() +LL | | } +LL | | } + | |_^ + | +note: this field is unused + --> $DIR/missing_fields_in_debug.rs:88:5 + | +LL | b: String, + | ^^^^^^^^^ + = help: consider including all fields in this `Debug` impl + = help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields + +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 3 previous errors +======= +error: manual `Debug` impl does not include all fields + --> $DIR/missing_fields_in_debug.rs:119:1 + | +LL | / impl fmt::Debug for MultiVariantEnum { +LL | | // match arm Self::B ignores `b` +LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { +LL | | match self { +... | +LL | | } +LL | | } + | |_^ + | +note: the field referenced by this binding is unused + --> $DIR/missing_fields_in_debug.rs:124:26 + | +LL | Self::B { a, b } => formatter.debug_struct("B").field("a", &a).finish(), + | ^ + = help: consider including all fields in this `Debug` impl + = help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields + +error: manual `Debug` impl does not include all fields + --> $DIR/missing_fields_in_debug.rs:170:1 + | +LL | / impl fmt::Debug for MultiVariantRest { +LL | | // `a` field ignored due to rest pattern +LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { +LL | | match self { +... | +LL | | } +LL | | } + | |_^ + | +note: more unused fields here due to rest pattern `..` + --> $DIR/missing_fields_in_debug.rs:175:13 + | +LL | Self::B { b, .. } => formatter.debug_struct("B").field("b", &b).finish(), + | ^^^^^^^^^^^^^^^^^ + = help: consider including all fields in this `Debug` impl + = help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields + +error: aborting due to 5 previous errors +>>>>>>> f74ec6b1b (new lint: `missing_field_in_debug`) +======= +error: aborting due to 3 previous errors +>>>>>>> a859b0e6d (don't lint enums, update note in lint description) + diff --git a/tests/ui/missing_inline_proc_macro.rs b/tests/ui/missing_inline_proc_macro.rs index 3c68fb905f12..e47a198c6aea 100644 --- a/tests/ui/missing_inline_proc_macro.rs +++ b/tests/ui/missing_inline_proc_macro.rs @@ -1,5 +1,4 @@ #![warn(clippy::missing_inline_in_public_items)] -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/missing_panics_doc.rs b/tests/ui/missing_panics_doc.rs index 7dc44529206d..72503b47bb9a 100644 --- a/tests/ui/missing_panics_doc.rs +++ b/tests/ui/missing_panics_doc.rs @@ -1,5 +1,21 @@ +//@aux-build:macro_rules.rs #![warn(clippy::missing_panics_doc)] -#![allow(clippy::option_map_unit_fn)] +#![allow(clippy::option_map_unit_fn, clippy::unnecessary_literal_unwrap)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + +#[macro_use] +extern crate macro_rules; + +use macro_rules::macro_with_panic; + +<<<<<<< HEAD +======= +>>>>>>> bfd5abad4 (Fix all the other tests) +======= +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) fn main() {} /// This needs to be documented @@ -13,11 +29,6 @@ pub fn panic() { panic!("This function panics") } -/// This needs to be documented -pub fn todo() { - todo!() -} - /// This needs to be documented pub fn inner_body(opt: Option) { opt.map(|x| { @@ -76,15 +87,6 @@ pub fn inner_body_documented(opt: Option) { }); } -/// This is documented -/// -/// # Panics -/// -/// We still need to do this part -pub fn todo_documented() { - todo!() -} - /// This is documented /// /// # Panics @@ -114,6 +116,11 @@ pub fn assert_ne_documented() { assert_ne!(x, 0); } +/// `todo!()` is fine +pub fn todo() { + todo!() +} + /// This is okay because it is private fn unwrap_private() { let result = Err("Hi"); @@ -125,11 +132,6 @@ fn panic_private() { panic!("This function panics") } -/// This is okay because it is private -fn todo_private() { - todo!() -} - /// This is okay because it is private fn inner_body_private(opt: Option) { opt.map(|x| { @@ -151,3 +153,59 @@ pub fn debug_assertions() { debug_assert_eq!(1, 2); debug_assert_ne!(1, 2); } + +// all function must be triggered the lint. +// `pub` is required, because the lint does not consider unreachable items +pub mod issue10240 { + pub fn option_unwrap(v: &[T]) -> &T { + let o: Option<&T> = v.last(); + o.unwrap() + } + + pub fn option_expect(v: &[T]) -> &T { + let o: Option<&T> = v.last(); + o.expect("passed an empty thing") + } + + pub fn result_unwrap(v: &[T]) -> &T { + let res: Result<&T, &str> = v.last().ok_or("oh noes"); + res.unwrap() + } + + pub fn result_expect(v: &[T]) -> &T { + let res: Result<&T, &str> = v.last().ok_or("oh noes"); + res.expect("passed an empty thing") + } + + pub fn last_unwrap(v: &[u32]) -> u32 { + *v.last().unwrap() + } + + pub fn last_expect(v: &[u32]) -> u32 { + *v.last().expect("passed an empty thing") + } +} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + +fn from_external_macro_should_not_lint() { + macro_with_panic!() +} + +macro_rules! some_macro_that_panics { + () => { + panic!() + }; +} + +fn from_declared_macro_should_lint_at_macrosite() { + // Not here. + some_macro_that_panics!() +} +<<<<<<< HEAD +======= +>>>>>>> 73cd2cde8 (merge test) +======= +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) diff --git a/tests/ui/missing_panics_doc.stderr b/tests/ui/missing_panics_doc.stderr index 183c262ce0b5..7a98d21270ed 100644 --- a/tests/ui/missing_panics_doc.stderr +++ b/tests/ui/missing_panics_doc.stderr @@ -1,87 +1,251 @@ error: docs for function which may panic missing `# Panics` section - --> $DIR/missing_panics_doc.rs:6:1 + --> $DIR/missing_panics_doc.rs:13:1 | LL | pub fn unwrap() { | ^^^^^^^^^^^^^^^ | note: first possible panic found here - --> $DIR/missing_panics_doc.rs:8:5 + --> $DIR/missing_panics_doc.rs:15:5 | LL | result.unwrap() | ^^^^^^^^^^^^^^^ = note: `-D clippy::missing-panics-doc` implied by `-D warnings` error: docs for function which may panic missing `# Panics` section - --> $DIR/missing_panics_doc.rs:12:1 + --> $DIR/missing_panics_doc.rs:19:1 | LL | pub fn panic() { | ^^^^^^^^^^^^^^ | note: first possible panic found here - --> $DIR/missing_panics_doc.rs:13:5 + --> $DIR/missing_panics_doc.rs:20:5 | LL | panic!("This function panics") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> $DIR/missing_panics_doc.rs:17:1 - | -LL | pub fn todo() { - | ^^^^^^^^^^^^^ - | -note: first possible panic found here - --> $DIR/missing_panics_doc.rs:18:5 - | -LL | todo!() - | ^^^^^^^ - -error: docs for function which may panic missing `# Panics` section - --> $DIR/missing_panics_doc.rs:22:1 + --> $DIR/missing_panics_doc.rs:24:1 | LL | pub fn inner_body(opt: Option) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> $DIR/missing_panics_doc.rs:25:13 + --> $DIR/missing_panics_doc.rs:27:13 | LL | panic!() | ^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> $DIR/missing_panics_doc.rs:31:1 + --> $DIR/missing_panics_doc.rs:33:1 | LL | pub fn unreachable_and_panic() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> $DIR/missing_panics_doc.rs:32:39 + --> $DIR/missing_panics_doc.rs:34:39 | LL | if true { unreachable!() } else { panic!() } | ^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> $DIR/missing_panics_doc.rs:36:1 + --> $DIR/missing_panics_doc.rs:38:1 | LL | pub fn assert_eq() { | ^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> $DIR/missing_panics_doc.rs:38:5 + --> $DIR/missing_panics_doc.rs:40:5 | LL | assert_eq!(x, 0); | ^^^^^^^^^^^^^^^^ error: docs for function which may panic missing `# Panics` section - --> $DIR/missing_panics_doc.rs:42:1 + --> $DIR/missing_panics_doc.rs:44:1 | LL | pub fn assert_ne() { | ^^^^^^^^^^^^^^^^^^ | note: first possible panic found here - --> $DIR/missing_panics_doc.rs:44:5 + --> $DIR/missing_panics_doc.rs:46:5 | LL | assert_ne!(x, 0); | ^^^^^^^^^^^^^^^^ -error: aborting due to 7 previous errors +error: docs for function which may panic missing `# Panics` section +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:151:5 +======= + --> $DIR/missing_panics_doc.rs:158:5 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:151:5 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | pub fn option_unwrap(v: &[T]) -> &T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first possible panic found here +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:153:9 +======= + --> $DIR/missing_panics_doc.rs:160:9 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:153:9 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | o.unwrap() + | ^^^^^^^^^^ + +error: docs for function which may panic missing `# Panics` section +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:156:5 +======= + --> $DIR/missing_panics_doc.rs:163:5 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:156:5 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | pub fn option_expect(v: &[T]) -> &T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first possible panic found here +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:158:9 +======= + --> $DIR/missing_panics_doc.rs:165:9 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:158:9 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | o.expect("passed an empty thing") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: docs for function which may panic missing `# Panics` section +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:161:5 +======= + --> $DIR/missing_panics_doc.rs:168:5 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:161:5 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | pub fn result_unwrap(v: &[T]) -> &T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first possible panic found here +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:163:9 +======= + --> $DIR/missing_panics_doc.rs:170:9 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:163:9 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | res.unwrap() + | ^^^^^^^^^^^^ + +error: docs for function which may panic missing `# Panics` section +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:166:5 +======= + --> $DIR/missing_panics_doc.rs:173:5 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:166:5 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | pub fn result_expect(v: &[T]) -> &T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first possible panic found here +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:168:9 +======= + --> $DIR/missing_panics_doc.rs:175:9 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:168:9 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | res.expect("passed an empty thing") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: docs for function which may panic missing `# Panics` section +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:171:5 +======= + --> $DIR/missing_panics_doc.rs:178:5 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:171:5 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | pub fn last_unwrap(v: &[u32]) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first possible panic found here +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:172:10 +======= + --> $DIR/missing_panics_doc.rs:179:10 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:172:10 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | *v.last().unwrap() + | ^^^^^^^^^^^^^^^^^ + +error: docs for function which may panic missing `# Panics` section +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:175:5 +======= + --> $DIR/missing_panics_doc.rs:182:5 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:175:5 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | pub fn last_expect(v: &[u32]) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first possible panic found here +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/missing_panics_doc.rs:176:10 +======= + --> $DIR/missing_panics_doc.rs:183:10 +>>>>>>> 73cd2cde8 (merge test) +======= + --> $DIR/missing_panics_doc.rs:176:10 +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) + | +LL | *v.last().expect("passed an empty thing") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 12 previous errors +======= +error: aborting due to 13 previous errors +>>>>>>> 73cd2cde8 (merge test) +======= +error: aborting due to 12 previous errors +>>>>>>> a6346d7c9 (`missing_panics_in_doc` bless test and add additional macro testcase) diff --git a/tests/ui/missing_spin_loop.fixed b/tests/ui/missing_spin_loop.fixed index aa89e04d26eb..a15298dc37b2 100644 --- a/tests/ui/missing_spin_loop.fixed +++ b/tests/ui/missing_spin_loop.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::missing_spin_loop)] #![allow(clippy::bool_comparison)] #![allow(unused_braces)] diff --git a/tests/ui/missing_spin_loop.rs b/tests/ui/missing_spin_loop.rs index 88745e477324..be74581ecd03 100644 --- a/tests/ui/missing_spin_loop.rs +++ b/tests/ui/missing_spin_loop.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::missing_spin_loop)] #![allow(clippy::bool_comparison)] #![allow(unused_braces)] diff --git a/tests/ui/missing_spin_loop.stderr b/tests/ui/missing_spin_loop.stderr index 485da00dc640..5795c2c21906 100644 --- a/tests/ui/missing_spin_loop.stderr +++ b/tests/ui/missing_spin_loop.stderr @@ -2,7 +2,7 @@ error: busy-waiting loop should at least have a spin loop hint --> $DIR/missing_spin_loop.rs:11:37 | LL | while b.load(Ordering::Acquire) {} - | ^^ help: try this: `{ std::hint::spin_loop() }` + | ^^ help: try: `{ std::hint::spin_loop() }` | = note: `-D clippy::missing-spin-loop` implied by `-D warnings` @@ -10,31 +10,31 @@ error: busy-waiting loop should at least have a spin loop hint --> $DIR/missing_spin_loop.rs:13:37 | LL | while !b.load(Ordering::SeqCst) {} - | ^^ help: try this: `{ std::hint::spin_loop() }` + | ^^ help: try: `{ std::hint::spin_loop() }` error: busy-waiting loop should at least have a spin loop hint --> $DIR/missing_spin_loop.rs:15:46 | LL | while b.load(Ordering::Acquire) == false {} - | ^^ help: try this: `{ std::hint::spin_loop() }` + | ^^ help: try: `{ std::hint::spin_loop() }` error: busy-waiting loop should at least have a spin loop hint --> $DIR/missing_spin_loop.rs:17:49 | LL | while { true == b.load(Ordering::Acquire) } {} - | ^^ help: try this: `{ std::hint::spin_loop() }` + | ^^ help: try: `{ std::hint::spin_loop() }` error: busy-waiting loop should at least have a spin loop hint --> $DIR/missing_spin_loop.rs:19:93 | LL | while b.compare_exchange(true, false, Ordering::Acquire, Ordering::Relaxed) != Ok(true) {} - | ^^ help: try this: `{ std::hint::spin_loop() }` + | ^^ help: try: `{ std::hint::spin_loop() }` error: busy-waiting loop should at least have a spin loop hint --> $DIR/missing_spin_loop.rs:21:94 | LL | while Ok(false) != b.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) {} - | ^^ help: try this: `{ std::hint::spin_loop() }` + | ^^ help: try: `{ std::hint::spin_loop() }` error: aborting due to 6 previous errors diff --git a/tests/ui/missing_spin_loop_no_std.fixed b/tests/ui/missing_spin_loop_no_std.fixed index bb4b4795516e..960e5c05fb63 100644 --- a/tests/ui/missing_spin_loop_no_std.fixed +++ b/tests/ui/missing_spin_loop_no_std.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::missing_spin_loop)] #![feature(lang_items, start, libc)] #![no_std] diff --git a/tests/ui/missing_spin_loop_no_std.rs b/tests/ui/missing_spin_loop_no_std.rs index a19bc72baf8d..e532ca62dc53 100644 --- a/tests/ui/missing_spin_loop_no_std.rs +++ b/tests/ui/missing_spin_loop_no_std.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::missing_spin_loop)] #![feature(lang_items, start, libc)] #![no_std] diff --git a/tests/ui/missing_spin_loop_no_std.stderr b/tests/ui/missing_spin_loop_no_std.stderr index 2b3b6873c3c4..3322a7aae5f6 100644 --- a/tests/ui/missing_spin_loop_no_std.stderr +++ b/tests/ui/missing_spin_loop_no_std.stderr @@ -2,7 +2,7 @@ error: busy-waiting loop should at least have a spin loop hint --> $DIR/missing_spin_loop_no_std.rs:13:37 | LL | while b.load(Ordering::Acquire) {} - | ^^ help: try this: `{ core::hint::spin_loop() }` + | ^^ help: try: `{ core::hint::spin_loop() }` | = note: `-D clippy::missing-spin-loop` implied by `-D warnings` diff --git a/tests/ui/mistyped_literal_suffix.fixed b/tests/ui/mistyped_literal_suffix.fixed index 9a47d7c56ed1..3cb1ee05f094 100644 --- a/tests/ui/mistyped_literal_suffix.fixed +++ b/tests/ui/mistyped_literal_suffix.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow( dead_code, diff --git a/tests/ui/mistyped_literal_suffix.rs b/tests/ui/mistyped_literal_suffix.rs index 04261cba55aa..4ea006c870cc 100644 --- a/tests/ui/mistyped_literal_suffix.rs +++ b/tests/ui/mistyped_literal_suffix.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow( dead_code, diff --git a/tests/ui/module_inception.rs b/tests/ui/module_inception.rs index a23aba9164a5..802c3ec39b64 100644 --- a/tests/ui/module_inception.rs +++ b/tests/ui/module_inception.rs @@ -1,5 +1,17 @@ #![warn(clippy::module_inception)] +pub mod foo2 { + pub mod bar2 { + pub mod bar2 { + pub mod foo2 {} + } + pub mod foo2 {} + } + pub mod foo2 { + pub mod bar2 {} + } +} + mod foo { mod bar { mod bar { diff --git a/tests/ui/module_inception.stderr b/tests/ui/module_inception.stderr index 77564dce9eb4..ebb8e296f464 100644 --- a/tests/ui/module_inception.stderr +++ b/tests/ui/module_inception.stderr @@ -1,8 +1,8 @@ error: module has the same name as its containing module --> $DIR/module_inception.rs:5:9 | -LL | / mod bar { -LL | | mod foo {} +LL | / pub mod bar2 { +LL | | pub mod foo2 {} LL | | } | |_________^ | @@ -11,10 +11,26 @@ LL | | } error: module has the same name as its containing module --> $DIR/module_inception.rs:10:5 | +LL | / pub mod foo2 { +LL | | pub mod bar2 {} +LL | | } + | |_____^ + +error: module has the same name as its containing module + --> $DIR/module_inception.rs:17:9 + | +LL | / mod bar { +LL | | mod foo {} +LL | | } + | |_________^ + +error: module has the same name as its containing module + --> $DIR/module_inception.rs:22:5 + | LL | / mod foo { LL | | mod bar {} LL | | } | |_____^ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/module_name_repetitions.rs b/tests/ui/module_name_repetitions.rs index ebaa77cc283e..fb2c7612343c 100644 --- a/tests/ui/module_name_repetitions.rs +++ b/tests/ui/module_name_repetitions.rs @@ -1,4 +1,4 @@ -// compile-flags: --test +//@compile-flags: --test #![warn(clippy::module_name_repetitions)] #![allow(dead_code)] diff --git a/tests/ui/modulo_one.stderr b/tests/ui/modulo_one.stderr index 04ecdef5e994..83a76f81d4e7 100644 --- a/tests/ui/modulo_one.stderr +++ b/tests/ui/modulo_one.stderr @@ -2,7 +2,7 @@ error: this operation will panic at runtime --> $DIR/modulo_one.rs:11:5 | LL | i32::MIN % (-1); // also caught by rustc - | ^^^^^^^^^^^^^^^ attempt to compute the remainder of `i32::MIN % -1_i32`, which would overflow + | ^^^^^^^^^^^^^^^ attempt to compute `i32::MIN % -1_i32`, which would overflow | = note: `#[deny(unconditional_panic)]` on by default @@ -10,13 +10,13 @@ error: this operation will panic at runtime --> $DIR/modulo_one.rs:21:5 | LL | INT_MIN % NEG_ONE; // also caught by rustc - | ^^^^^^^^^^^^^^^^^ attempt to compute the remainder of `i64::MIN % -1_i64`, which would overflow + | ^^^^^^^^^^^^^^^^^ attempt to compute `i64::MIN % -1_i64`, which would overflow error: this operation will panic at runtime --> $DIR/modulo_one.rs:22:5 | LL | INT_MIN % STATIC_NEG_ONE; // ONLY caught by rustc - | ^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute the remainder of `i64::MIN % -1_i64`, which would overflow + | ^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `i64::MIN % -1_i64`, which would overflow error: any number modulo 1 will be 0 --> $DIR/modulo_one.rs:8:5 diff --git a/tests/ui/multiple_unsafe_ops_per_block.rs b/tests/ui/multiple_unsafe_ops_per_block.rs index 9082f1675a87..78390e652428 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/tests/ui/multiple_unsafe_ops_per_block.rs @@ -1,8 +1,12 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(unused)] #![allow(deref_nullptr)] #![allow(clippy::unnecessary_operation)] -#![allow(clippy::drop_copy)] +#![allow(dropping_copy_types)] #![warn(clippy::multiple_unsafe_ops_per_block)] extern crate proc_macros; diff --git a/tests/ui/must_use_candidates.fixed b/tests/ui/must_use_candidates.fixed index bbbb3cf621e4..3ca20c07d9ba 100644 --- a/tests/ui/must_use_candidates.fixed +++ b/tests/ui/must_use_candidates.fixed @@ -1,6 +1,11 @@ -// run-rustfix +//@run-rustfix #![feature(never_type)] -#![allow(unused_mut, unused_tuple_struct_fields, clippy::redundant_allocation)] +#![allow( + unused_mut, + unused_tuple_struct_fields, + clippy::redundant_allocation, + clippy::needless_pass_by_ref_mut +)] #![warn(clippy::must_use_candidate)] use std::rc::Rc; use std::sync::atomic::{AtomicBool, Ordering}; diff --git a/tests/ui/must_use_candidates.rs b/tests/ui/must_use_candidates.rs index 94d3c83bdb93..dc4e0118ec72 100644 --- a/tests/ui/must_use_candidates.rs +++ b/tests/ui/must_use_candidates.rs @@ -1,6 +1,11 @@ -// run-rustfix +//@run-rustfix #![feature(never_type)] -#![allow(unused_mut, unused_tuple_struct_fields, clippy::redundant_allocation)] +#![allow( + unused_mut, + unused_tuple_struct_fields, + clippy::redundant_allocation, + clippy::needless_pass_by_ref_mut +)] #![warn(clippy::must_use_candidate)] use std::rc::Rc; use std::sync::atomic::{AtomicBool, Ordering}; diff --git a/tests/ui/must_use_candidates.stderr b/tests/ui/must_use_candidates.stderr index 0fa3849d03bf..5fb302ccbf14 100644 --- a/tests/ui/must_use_candidates.stderr +++ b/tests/ui/must_use_candidates.stderr @@ -1,5 +1,5 @@ error: this function could have a `#[must_use]` attribute - --> $DIR/must_use_candidates.rs:12:1 + --> $DIR/must_use_candidates.rs:17:1 | LL | pub fn pure(i: u8) -> u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn pure(i: u8) -> u8` @@ -7,25 +7,25 @@ LL | pub fn pure(i: u8) -> u8 { = note: `-D clippy::must-use-candidate` implied by `-D warnings` error: this method could have a `#[must_use]` attribute - --> $DIR/must_use_candidates.rs:17:5 + --> $DIR/must_use_candidates.rs:22:5 | LL | pub fn inherent_pure(&self) -> u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn inherent_pure(&self) -> u8` error: this function could have a `#[must_use]` attribute - --> $DIR/must_use_candidates.rs:48:1 + --> $DIR/must_use_candidates.rs:53:1 | LL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool` error: this function could have a `#[must_use]` attribute - --> $DIR/must_use_candidates.rs:60:1 + --> $DIR/must_use_candidates.rs:65:1 | LL | pub fn rcd(_x: Rc) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn rcd(_x: Rc) -> bool` error: this function could have a `#[must_use]` attribute - --> $DIR/must_use_candidates.rs:68:1 + --> $DIR/must_use_candidates.rs:73:1 | LL | pub fn arcd(_x: Arc) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn arcd(_x: Arc) -> bool` diff --git a/tests/ui/must_use_unit.fixed b/tests/ui/must_use_unit.fixed index b7d375ff80e1..9cd90d56306c 100644 --- a/tests/ui/must_use_unit.fixed +++ b/tests/ui/must_use_unit.fixed @@ -1,5 +1,9 @@ -//run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::must_use_unit)] #![allow(clippy::unused_unit)] diff --git a/tests/ui/must_use_unit.rs b/tests/ui/must_use_unit.rs index 74d6b4ca865c..e37fcd68308e 100644 --- a/tests/ui/must_use_unit.rs +++ b/tests/ui/must_use_unit.rs @@ -1,5 +1,9 @@ -//run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::must_use_unit)] #![allow(clippy::unused_unit)] diff --git a/tests/ui/mut_from_ref.rs b/tests/ui/mut_from_ref.rs index 7de153305947..8c0c23b65706 100644 --- a/tests/ui/mut_from_ref.rs +++ b/tests/ui/mut_from_ref.rs @@ -1,4 +1,4 @@ -#![allow(unused, clippy::needless_lifetimes)] +#![allow(unused, clippy::needless_lifetimes, clippy::needless_pass_by_ref_mut)] #![warn(clippy::mut_from_ref)] struct Foo; diff --git a/tests/ui/mut_key.rs b/tests/ui/mut_key.rs index 1c0ba664580a..15d68c08984f 100644 --- a/tests/ui/mut_key.rs +++ b/tests/ui/mut_key.rs @@ -2,7 +2,8 @@ use std::cell::Cell; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::hash::{Hash, Hasher}; use std::rc::Rc; -use std::sync::atomic::{AtomicUsize, Ordering::Relaxed}; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering::Relaxed; use std::sync::Arc; struct Key(AtomicUsize); diff --git a/tests/ui/mut_key.stderr b/tests/ui/mut_key.stderr index 25dd029b16ee..02a0da86a4b8 100644 --- a/tests/ui/mut_key.stderr +++ b/tests/ui/mut_key.stderr @@ -1,5 +1,5 @@ error: mutable key type - --> $DIR/mut_key.rs:30:32 + --> $DIR/mut_key.rs:31:32 | LL | fn should_not_take_this_arg(m: &mut HashMap, _n: usize) -> HashSet { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,100 +7,108 @@ LL | fn should_not_take_this_arg(m: &mut HashMap, _n: usize) -> Hash = note: `-D clippy::mutable-key-type` implied by `-D warnings` error: mutable key type - --> $DIR/mut_key.rs:30:72 + --> $DIR/mut_key.rs:31:72 | LL | fn should_not_take_this_arg(m: &mut HashMap, _n: usize) -> HashSet { | ^^^^^^^^^^^^ +error: this argument is a mutable reference, but not used mutably + --> $DIR/mut_key.rs:31:32 + | +LL | fn should_not_take_this_arg(m: &mut HashMap, _n: usize) -> HashSet { + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&HashMap` + | + = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` + error: mutable key type - --> $DIR/mut_key.rs:31:5 + --> $DIR/mut_key.rs:32:5 | LL | let _other: HashMap = HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:58:22 + --> $DIR/mut_key.rs:59:22 | LL | fn tuples_bad(_m: &mut HashMap<(Key, U), bool>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:70:5 + --> $DIR/mut_key.rs:71:5 | LL | let _map = HashMap::, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:71:5 + --> $DIR/mut_key.rs:72:5 | LL | let _map = HashMap::<&mut Cell, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:72:5 + --> $DIR/mut_key.rs:73:5 | LL | let _map = HashMap::<&mut usize, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:74:5 + --> $DIR/mut_key.rs:75:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:75:5 + --> $DIR/mut_key.rs:76:5 | LL | let _map = HashMap::, ()>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:76:5 + --> $DIR/mut_key.rs:77:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:77:5 + --> $DIR/mut_key.rs:78:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:78:5 + --> $DIR/mut_key.rs:79:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:79:5 + --> $DIR/mut_key.rs:80:5 | LL | let _map = HashMap::>>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:80:5 + --> $DIR/mut_key.rs:81:5 | LL | let _map = HashMap::, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:82:5 + --> $DIR/mut_key.rs:83:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:83:5 + --> $DIR/mut_key.rs:84:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> $DIR/mut_key.rs:84:5 + --> $DIR/mut_key.rs:85:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 17 previous errors +error: aborting due to 18 previous errors diff --git a/tests/ui/mut_mut.rs b/tests/ui/mut_mut.rs index 06bb085442a7..5c4e70c3072b 100644 --- a/tests/ui/mut_mut.rs +++ b/tests/ui/mut_mut.rs @@ -1,7 +1,16 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::mut_mut)] #![allow(unused)] -#![allow(clippy::no_effect, clippy::uninlined_format_args, clippy::unnecessary_operation)] +#![allow( + clippy::no_effect, + clippy::uninlined_format_args, + clippy::unnecessary_operation, + clippy::needless_pass_by_ref_mut +)] extern crate proc_macros; use proc_macros::{external, inline_macros}; diff --git a/tests/ui/mut_mut.stderr b/tests/ui/mut_mut.stderr index 93b857eb2074..58a1c4e683c9 100644 --- a/tests/ui/mut_mut.stderr +++ b/tests/ui/mut_mut.stderr @@ -1,5 +1,5 @@ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:9:11 + --> $DIR/mut_mut.rs:14:11 | LL | fn fun(x: &mut &mut u32) -> bool { | ^^^^^^^^^^^^^ @@ -7,13 +7,13 @@ LL | fn fun(x: &mut &mut u32) -> bool { = note: `-D clippy::mut-mut` implied by `-D warnings` error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:26:17 + --> $DIR/mut_mut.rs:31:17 | LL | let mut x = &mut &mut 1u32; | ^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:41:25 + --> $DIR/mut_mut.rs:46:25 | LL | let mut z = inline!(&mut $(&mut 3u32)); | ^ @@ -21,37 +21,37 @@ LL | let mut z = inline!(&mut $(&mut 3u32)); = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this expression mutably borrows a mutable reference. Consider reborrowing - --> $DIR/mut_mut.rs:28:21 + --> $DIR/mut_mut.rs:33:21 | LL | let mut y = &mut x; | ^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:32:32 + --> $DIR/mut_mut.rs:37:32 | LL | let y: &mut &mut u32 = &mut &mut 2; | ^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:32:16 + --> $DIR/mut_mut.rs:37:16 | LL | let y: &mut &mut u32 = &mut &mut 2; | ^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:37:37 + --> $DIR/mut_mut.rs:42:37 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:37:16 + --> $DIR/mut_mut.rs:42:16 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:37:21 + --> $DIR/mut_mut.rs:42:21 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^ diff --git a/tests/ui/mut_mutex_lock.fixed b/tests/ui/mut_mutex_lock.fixed index ecad10a82903..433817a4e03d 100644 --- a/tests/ui/mut_mutex_lock.fixed +++ b/tests/ui/mut_mutex_lock.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_mut)] #![warn(clippy::mut_mutex_lock)] diff --git a/tests/ui/mut_mutex_lock.rs b/tests/ui/mut_mutex_lock.rs index f2b1d6fbfbc3..567a0b59e703 100644 --- a/tests/ui/mut_mutex_lock.rs +++ b/tests/ui/mut_mutex_lock.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_mut)] #![warn(clippy::mut_mutex_lock)] diff --git a/tests/ui/mut_reference.stderr b/tests/ui/mut_reference.stderr index 062d30b262c1..23c812475c2a 100644 --- a/tests/ui/mut_reference.stderr +++ b/tests/ui/mut_reference.stderr @@ -1,3 +1,17 @@ +error: this argument is a mutable reference, but not used mutably + --> $DIR/mut_reference.rs:4:33 + | +LL | fn takes_a_mutable_reference(a: &mut i32) {} + | ^^^^^^^^ help: consider changing to: `&i32` + | + = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/mut_reference.rs:11:44 + | +LL | fn takes_a_mutable_reference(&self, a: &mut i32) {} + | ^^^^^^^^ help: consider changing to: `&i32` + error: the function `takes_an_immutable_reference` doesn't need a mutable reference --> $DIR/mut_reference.rs:17:34 | @@ -18,5 +32,5 @@ error: the method `takes_an_immutable_reference` doesn't need a mutable referenc LL | my_struct.takes_an_immutable_reference(&mut 42); | ^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors diff --git a/tests/ui/needless_arbitrary_self_type.fixed b/tests/ui/needless_arbitrary_self_type.fixed index 9da21eb6b29b..d7eb1a047ed3 100644 --- a/tests/ui/needless_arbitrary_self_type.fixed +++ b/tests/ui/needless_arbitrary_self_type.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_arbitrary_self_type)] #![allow(unused_mut, clippy::needless_lifetimes)] diff --git a/tests/ui/needless_arbitrary_self_type.rs b/tests/ui/needless_arbitrary_self_type.rs index 17aeaaf97ac7..85a2a957f29a 100644 --- a/tests/ui/needless_arbitrary_self_type.rs +++ b/tests/ui/needless_arbitrary_self_type.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_arbitrary_self_type)] #![allow(unused_mut, clippy::needless_lifetimes)] diff --git a/tests/ui/needless_arbitrary_self_type_unfixable.rs b/tests/ui/needless_arbitrary_self_type_unfixable.rs index 02b43cce2bd4..a42bc298d32f 100644 --- a/tests/ui/needless_arbitrary_self_type_unfixable.rs +++ b/tests/ui/needless_arbitrary_self_type_unfixable.rs @@ -1,4 +1,14 @@ -// aux-build:proc_macro_attr.rs +<<<<<<< HEAD +//@aux-build:proc_macro_attr.rs:proc-macro +<<<<<<< HEAD +// Flaky test, see https://github.com/rust-lang/rust/issues/113585. +//@ignore-32bit +//@ignore-64bit +======= +>>>>>>> 5bd97ac17 (Update tests) +======= +//@aux-build:proc_macro_attr.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::needless_arbitrary_self_type)] diff --git a/tests/ui/needless_bitwise_bool.fixed b/tests/ui/needless_bitwise_bool.fixed index 5e1ea663a107..7543ab72ca21 100644 --- a/tests/ui/needless_bitwise_bool.fixed +++ b/tests/ui/needless_bitwise_bool.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_bitwise_bool)] diff --git a/tests/ui/needless_bitwise_bool.rs b/tests/ui/needless_bitwise_bool.rs index f3075fba0a2d..2cea701dce63 100644 --- a/tests/ui/needless_bitwise_bool.rs +++ b/tests/ui/needless_bitwise_bool.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_bitwise_bool)] diff --git a/tests/ui/needless_bool/fixable.fixed b/tests/ui/needless_bool/fixable.fixed index 89dc13fd5b13..7d0e556528fa 100644 --- a/tests/ui/needless_bool/fixable.fixed +++ b/tests/ui/needless_bool/fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_bool)] #![allow( @@ -7,6 +7,7 @@ clippy::no_effect, clippy::if_same_then_else, clippy::equatable_if_let, + clippy::needless_if, clippy::needless_return, clippy::self_named_constructors )] @@ -63,6 +64,13 @@ fn main() { needless_bool2(x); needless_bool3(x); needless_bool_condition(); + + if a == b { + true + } else { + // Do not lint as this comment might be important + false + }; } fn bool_ret3(x: bool) -> bool { diff --git a/tests/ui/needless_bool/fixable.rs b/tests/ui/needless_bool/fixable.rs index c11d9472e8d0..88bfe8af7337 100644 --- a/tests/ui/needless_bool/fixable.rs +++ b/tests/ui/needless_bool/fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_bool)] #![allow( @@ -7,6 +7,7 @@ clippy::no_effect, clippy::if_same_then_else, clippy::equatable_if_let, + clippy::needless_if, clippy::needless_return, clippy::self_named_constructors )] @@ -99,6 +100,13 @@ fn main() { needless_bool2(x); needless_bool3(x); needless_bool_condition(); + + if a == b { + true + } else { + // Do not lint as this comment might be important + false + }; } fn bool_ret3(x: bool) -> bool { diff --git a/tests/ui/needless_bool/fixable.stderr b/tests/ui/needless_bool/fixable.stderr index d2c48376f766..f9c842970f7b 100644 --- a/tests/ui/needless_bool/fixable.stderr +++ b/tests/ui/needless_bool/fixable.stderr @@ -1,5 +1,5 @@ error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:41:5 + --> $DIR/fixable.rs:42:5 | LL | / if x { LL | | true @@ -11,7 +11,7 @@ LL | | }; = note: `-D clippy::needless-bool` implied by `-D warnings` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:46:5 + --> $DIR/fixable.rs:47:5 | LL | / if x { LL | | false @@ -21,7 +21,7 @@ LL | | }; | |_____^ help: you can reduce it to: `!x` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:51:5 + --> $DIR/fixable.rs:52:5 | LL | / if x && y { LL | | false @@ -31,7 +31,7 @@ LL | | }; | |_____^ help: you can reduce it to: `!(x && y)` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:59:5 + --> $DIR/fixable.rs:60:5 | LL | / if a == b { LL | | false @@ -41,7 +41,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a != b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:64:5 + --> $DIR/fixable.rs:65:5 | LL | / if a != b { LL | | false @@ -51,7 +51,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a == b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:69:5 + --> $DIR/fixable.rs:70:5 | LL | / if a < b { LL | | false @@ -61,7 +61,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a >= b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:74:5 + --> $DIR/fixable.rs:75:5 | LL | / if a <= b { LL | | false @@ -71,7 +71,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a > b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:79:5 + --> $DIR/fixable.rs:80:5 | LL | / if a > b { LL | | false @@ -81,7 +81,7 @@ LL | | }; | |_____^ help: you can reduce it to: `a <= b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:84:5 + --> $DIR/fixable.rs:85:5 | LL | / if a >= b { LL | | false @@ -91,7 +91,11 @@ LL | | }; | |_____^ help: you can reduce it to: `a < b` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:105:5 +<<<<<<< HEAD + --> $DIR/fixable.rs:113:5 +======= + --> $DIR/fixable.rs:112:5 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | / if x { LL | | return true; @@ -101,7 +105,11 @@ LL | | }; | |_____^ help: you can reduce it to: `return x` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:113:5 +<<<<<<< HEAD + --> $DIR/fixable.rs:121:5 +======= + --> $DIR/fixable.rs:120:5 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | / if x { LL | | return false; @@ -111,7 +119,11 @@ LL | | }; | |_____^ help: you can reduce it to: `return !x` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:121:5 +<<<<<<< HEAD + --> $DIR/fixable.rs:129:5 +======= + --> $DIR/fixable.rs:128:5 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | / if x && y { LL | | return true; @@ -121,7 +133,11 @@ LL | | }; | |_____^ help: you can reduce it to: `return x && y` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:129:5 +<<<<<<< HEAD + --> $DIR/fixable.rs:137:5 +======= + --> $DIR/fixable.rs:136:5 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | / if x && y { LL | | return false; @@ -131,7 +147,11 @@ LL | | }; | |_____^ help: you can reduce it to: `return !(x && y)` error: equality checks against true are unnecessary - --> $DIR/fixable.rs:137:8 +<<<<<<< HEAD + --> $DIR/fixable.rs:145:8 +======= + --> $DIR/fixable.rs:144:8 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | if x == true {}; | ^^^^^^^^^ help: try simplifying it as shown: `x` @@ -139,25 +159,41 @@ LL | if x == true {}; = note: `-D clippy::bool-comparison` implied by `-D warnings` error: equality checks against false can be replaced by a negation - --> $DIR/fixable.rs:141:8 +<<<<<<< HEAD + --> $DIR/fixable.rs:149:8 +======= + --> $DIR/fixable.rs:148:8 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | if x == false {}; | ^^^^^^^^^^ help: try simplifying it as shown: `!x` error: equality checks against true are unnecessary - --> $DIR/fixable.rs:151:8 +<<<<<<< HEAD + --> $DIR/fixable.rs:159:8 +======= + --> $DIR/fixable.rs:158:8 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | if x == true {}; | ^^^^^^^^^ help: try simplifying it as shown: `x` error: equality checks against false can be replaced by a negation - --> $DIR/fixable.rs:152:8 +<<<<<<< HEAD + --> $DIR/fixable.rs:160:8 +======= + --> $DIR/fixable.rs:159:8 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | if x == false {}; | ^^^^^^^^^^ help: try simplifying it as shown: `!x` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:161:12 +<<<<<<< HEAD + --> $DIR/fixable.rs:169:12 +======= + --> $DIR/fixable.rs:168:12 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | } else if returns_bool() { | ____________^ @@ -168,7 +204,11 @@ LL | | }; | |_____^ help: you can reduce it to: `{ !returns_bool() }` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:174:5 +<<<<<<< HEAD + --> $DIR/fixable.rs:182:5 +======= + --> $DIR/fixable.rs:181:5 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | / if unsafe { no(4) } & 1 != 0 { LL | | true @@ -178,13 +218,21 @@ LL | | }; | |_____^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:179:30 +<<<<<<< HEAD + --> $DIR/fixable.rs:187:30 +======= + --> $DIR/fixable.rs:186:30 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | let _brackets_unneeded = if unsafe { no(4) } & 1 != 0 { true } else { false }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `unsafe { no(4) } & 1 != 0` error: this if-then-else expression returns a bool literal - --> $DIR/fixable.rs:182:9 +<<<<<<< HEAD + --> $DIR/fixable.rs:190:9 +======= + --> $DIR/fixable.rs:189:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | if unsafe { no(4) } & 1 != 0 { true } else { false } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)` diff --git a/tests/ui/needless_bool_assign.fixed b/tests/ui/needless_bool_assign.fixed new file mode 100644 index 000000000000..3ed31d4d711f --- /dev/null +++ b/tests/ui/needless_bool_assign.fixed @@ -0,0 +1,33 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::needless_bool_assign)] + +fn random() -> bool { + true +} + +fn main() { + struct Data { + field: bool, + }; + let mut a = Data { field: false }; + a.field = random() && random(); + a.field = !(random() && random()); + // Do not lint… + if random() { + a.field = false; + } else { + // …to avoid losing this comment + a.field = true + } + // This one also triggers lint `clippy::if_same_then_else` + // which does not suggest a rewrite. + random(); a.field = true; + let mut b = false; + if random() { + a.field = false; + } else { + b = true; + } +} diff --git a/tests/ui/needless_bool_assign.rs b/tests/ui/needless_bool_assign.rs new file mode 100644 index 000000000000..efaeb67fa45d --- /dev/null +++ b/tests/ui/needless_bool_assign.rs @@ -0,0 +1,45 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::needless_bool_assign)] + +fn random() -> bool { + true +} + +fn main() { + struct Data { + field: bool, + }; + let mut a = Data { field: false }; + if random() && random() { + a.field = true; + } else { + a.field = false + } + if random() && random() { + a.field = false; + } else { + a.field = true + } + // Do not lint… + if random() { + a.field = false; + } else { + // …to avoid losing this comment + a.field = true + } + // This one also triggers lint `clippy::if_same_then_else` + // which does not suggest a rewrite. + if random() { + a.field = true; + } else { + a.field = true; + } + let mut b = false; + if random() { + a.field = false; + } else { + b = true; + } +} diff --git a/tests/ui/needless_bool_assign.stderr b/tests/ui/needless_bool_assign.stderr new file mode 100644 index 000000000000..601bbed5493b --- /dev/null +++ b/tests/ui/needless_bool_assign.stderr @@ -0,0 +1,53 @@ +error: this if-then-else expression assigns a bool literal + --> $DIR/needless_bool_assign.rs:15:5 + | +LL | / if random() && random() { +LL | | a.field = true; +LL | | } else { +LL | | a.field = false +LL | | } + | |_____^ help: you can reduce it to: `a.field = random() && random();` + | + = note: `-D clippy::needless-bool-assign` implied by `-D warnings` + +error: this if-then-else expression assigns a bool literal + --> $DIR/needless_bool_assign.rs:20:5 + | +LL | / if random() && random() { +LL | | a.field = false; +LL | | } else { +LL | | a.field = true +LL | | } + | |_____^ help: you can reduce it to: `a.field = !(random() && random());` + +error: this if-then-else expression assigns a bool literal + --> $DIR/needless_bool_assign.rs:34:5 + | +LL | / if random() { +LL | | a.field = true; +LL | | } else { +LL | | a.field = true; +LL | | } + | |_____^ help: you can reduce it to: `random(); a.field = true;` + +error: this `if` has identical blocks + --> $DIR/needless_bool_assign.rs:34:17 + | +LL | if random() { + | _________________^ +LL | | a.field = true; +LL | | } else { + | |_____^ + | +note: same as this + --> $DIR/needless_bool_assign.rs:36:12 + | +LL | } else { + | ____________^ +LL | | a.field = true; +LL | | } + | |_____^ + = note: `#[deny(clippy::if_same_then_else)]` on by default + +error: aborting due to 4 previous errors + diff --git a/tests/ui/needless_borrow.fixed b/tests/ui/needless_borrow.fixed index 4cb7f6b687f1..1dfbee150d78 100644 --- a/tests/ui/needless_borrow.fixed +++ b/tests/ui/needless_borrow.fixed @@ -1,10 +1,11 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![allow( unused, clippy::uninlined_format_args, clippy::unnecessary_mut_passed, - clippy::unnecessary_to_owned + clippy::unnecessary_to_owned, + clippy::unnecessary_literal_unwrap )] #![warn(clippy::needless_borrow)] @@ -491,3 +492,15 @@ mod issue_9782_method_variant { S.foo::<&[u8; 100]>(&a); } } + +mod issue_10535 { + static SOME_STATIC: String = String::new(); + + static UNIT: () = compute(&SOME_STATIC); + + pub const fn compute(_: T) + where + T: Copy, + { + } +} diff --git a/tests/ui/needless_borrow.rs b/tests/ui/needless_borrow.rs index 9a01190ed8db..3c0d73f5f025 100644 --- a/tests/ui/needless_borrow.rs +++ b/tests/ui/needless_borrow.rs @@ -1,10 +1,11 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![allow( unused, clippy::uninlined_format_args, clippy::unnecessary_mut_passed, - clippy::unnecessary_to_owned + clippy::unnecessary_to_owned, + clippy::unnecessary_literal_unwrap )] #![warn(clippy::needless_borrow)] @@ -491,3 +492,15 @@ mod issue_9782_method_variant { S.foo::<&[u8; 100]>(&a); } } + +mod issue_10535 { + static SOME_STATIC: String = String::new(); + + static UNIT: () = compute(&SOME_STATIC); + + pub const fn compute(_: T) + where + T: Copy, + { + } +} diff --git a/tests/ui/needless_borrow.stderr b/tests/ui/needless_borrow.stderr index d26c317124b8..f85b4fb46a65 100644 --- a/tests/ui/needless_borrow.stderr +++ b/tests/ui/needless_borrow.stderr @@ -1,5 +1,5 @@ error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:15:15 + --> $DIR/needless_borrow.rs:16:15 | LL | let _ = x(&&a); // warn | ^^^ help: change this to: `&a` @@ -7,211 +7,211 @@ LL | let _ = x(&&a); // warn = note: `-D clippy::needless-borrow` implied by `-D warnings` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:19:13 + --> $DIR/needless_borrow.rs:20:13 | LL | mut_ref(&mut &mut b); // warn | ^^^^^^^^^^^ help: change this to: `&mut b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:31:13 + --> $DIR/needless_borrow.rs:32:13 | LL | &&a | ^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:33:15 + --> $DIR/needless_borrow.rs:34:15 | LL | 46 => &&a, | ^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:39:27 + --> $DIR/needless_borrow.rs:40:27 | LL | break &ref_a; | ^^^^^^ help: change this to: `ref_a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:46:15 + --> $DIR/needless_borrow.rs:47:15 | LL | let _ = x(&&&a); | ^^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:47:15 + --> $DIR/needless_borrow.rs:48:15 | LL | let _ = x(&mut &&a); | ^^^^^^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:48:15 + --> $DIR/needless_borrow.rs:49:15 | LL | let _ = x(&&&mut b); | ^^^^^^^^ help: change this to: `&mut b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:49:15 + --> $DIR/needless_borrow.rs:50:15 | LL | let _ = x(&&ref_a); | ^^^^^^^ help: change this to: `ref_a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:52:11 + --> $DIR/needless_borrow.rs:53:11 | LL | x(&b); | ^^ help: change this to: `b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:59:13 + --> $DIR/needless_borrow.rs:60:13 | LL | mut_ref(&mut x); | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:60:13 + --> $DIR/needless_borrow.rs:61:13 | LL | mut_ref(&mut &mut x); | ^^^^^^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:61:23 + --> $DIR/needless_borrow.rs:62:23 | LL | let y: &mut i32 = &mut x; | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:62:23 + --> $DIR/needless_borrow.rs:63:23 | LL | let y: &mut i32 = &mut &mut x; | ^^^^^^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:71:14 + --> $DIR/needless_borrow.rs:72:14 | LL | 0 => &mut x, | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:77:14 + --> $DIR/needless_borrow.rs:78:14 | LL | 0 => &mut x, | ^^^^^^ help: change this to: `x` error: this expression borrows a value the compiler would automatically borrow - --> $DIR/needless_borrow.rs:89:13 + --> $DIR/needless_borrow.rs:90:13 | LL | let _ = (&x).0; | ^^^^ help: change this to: `x` error: this expression borrows a value the compiler would automatically borrow - --> $DIR/needless_borrow.rs:91:22 + --> $DIR/needless_borrow.rs:92:22 | LL | let _ = unsafe { (&*x).0 }; | ^^^^^ help: change this to: `(*x)` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:101:5 + --> $DIR/needless_borrow.rs:102:5 | LL | (&&()).foo(); | ^^^^^^ help: change this to: `(&())` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:110:5 + --> $DIR/needless_borrow.rs:111:5 | LL | (&&5).foo(); | ^^^^^ help: change this to: `(&5)` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:135:51 + --> $DIR/needless_borrow.rs:136:51 | LL | let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap(); | ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:136:44 + --> $DIR/needless_borrow.rs:137:44 | LL | let _ = std::path::Path::new(".").join(&&"."); | ^^^^^ help: change this to: `"."` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:137:23 + --> $DIR/needless_borrow.rs:138:23 | LL | deref_target_is_x(&X); | ^^ help: change this to: `X` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:138:26 + --> $DIR/needless_borrow.rs:139:26 | LL | multiple_constraints(&[[""]]); | ^^^^^^^ help: change this to: `[[""]]` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:139:45 + --> $DIR/needless_borrow.rs:140:45 | LL | multiple_constraints_normalizes_to_same(&X, X); | ^^ help: change this to: `X` error: this expression creates a reference which is immediately dereferenced by the compiler - --> $DIR/needless_borrow.rs:140:32 + --> $DIR/needless_borrow.rs:141:32 | LL | let _ = Some("").unwrap_or(&""); | ^^^ help: change this to: `""` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:141:33 + --> $DIR/needless_borrow.rs:142:33 | LL | let _ = std::fs::write("x", &"".to_string()); | ^^^^^^^^^^^^^^^ help: change this to: `"".to_string()` error: this expression borrows a value the compiler would automatically borrow - --> $DIR/needless_borrow.rs:190:13 + --> $DIR/needless_borrow.rs:191:13 | LL | (&self.f)() | ^^^^^^^^^ help: change this to: `(self.f)` error: this expression borrows a value the compiler would automatically borrow - --> $DIR/needless_borrow.rs:199:13 + --> $DIR/needless_borrow.rs:200:13 | LL | (&mut self.f)() | ^^^^^^^^^^^^^ help: change this to: `(self.f)` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:283:20 + --> $DIR/needless_borrow.rs:284:20 | LL | takes_iter(&mut x) | ^^^^^^ help: change this to: `x` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:297:55 + --> $DIR/needless_borrow.rs:298:55 | LL | let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap(); | ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:335:37 + --> $DIR/needless_borrow.rs:336:37 | LL | let _ = std::fs::write("x", &arg); | ^^^^ help: change this to: `arg` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:336:37 + --> $DIR/needless_borrow.rs:337:37 | LL | let _ = std::fs::write("x", &loc); | ^^^^ help: change this to: `loc` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:354:15 + --> $DIR/needless_borrow.rs:355:15 | LL | debug(&x); | ^^ help: change this to: `x` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:363:15 + --> $DIR/needless_borrow.rs:364:15 | LL | use_x(&x); | ^^ help: change this to: `x` error: the borrowed expression implements the required traits - --> $DIR/needless_borrow.rs:457:13 + --> $DIR/needless_borrow.rs:458:13 | LL | foo(&a); | ^^ help: change this to: `a` diff --git a/tests/ui/needless_borrow_pat.stderr b/tests/ui/needless_borrow_pat.stderr index db3b52b8850e..2d9b8f159021 100644 --- a/tests/ui/needless_borrow_pat.stderr +++ b/tests/ui/needless_borrow_pat.stderr @@ -2,7 +2,7 @@ error: this pattern creates a reference to a reference --> $DIR/needless_borrow_pat.rs:59:14 | LL | Some(ref x) => x, - | ^^^^^ help: try this: `x` + | ^^^^^ help: try: `x` | = note: `-D clippy::needless-borrow` implied by `-D warnings` @@ -12,7 +12,7 @@ error: this pattern creates a reference to a reference LL | Some(ref x) => *x, | ^^^^^ | -help: try this +help: try | LL | Some(x) => x, | ~ ~ @@ -23,7 +23,7 @@ error: this pattern creates a reference to a reference LL | Some(ref x) => { | ^^^^^ | -help: try this +help: try | LL ~ Some(x) => { LL | f1(x); @@ -34,13 +34,13 @@ error: this pattern creates a reference to a reference --> $DIR/needless_borrow_pat.rs:81:14 | LL | Some(ref x) => m1!(x), - | ^^^^^ help: try this: `x` + | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference --> $DIR/needless_borrow_pat.rs:86:15 | LL | let _ = |&ref x: &&String| { - | ^^^^^ help: try this: `x` + | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference --> $DIR/needless_borrow_pat.rs:91:10 @@ -48,7 +48,7 @@ error: this pattern creates a reference to a reference LL | let (ref y,) = (&x,); | ^^^^^ | -help: try this +help: try | LL ~ let (y,) = (&x,); LL ~ let _: &String = y; @@ -58,7 +58,7 @@ error: this pattern creates a reference to a reference --> $DIR/needless_borrow_pat.rs:101:14 | LL | Some(ref x) => x.0, - | ^^^^^ help: try this: `x` + | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference --> $DIR/needless_borrow_pat.rs:111:14 @@ -66,7 +66,7 @@ error: this pattern creates a reference to a reference LL | E::A(ref x) | E::B(ref x) => *x, | ^^^^^ ^^^^^ | -help: try this +help: try | LL | E::A(x) | E::B(x) => x, | ~ ~ ~ @@ -75,7 +75,7 @@ error: this pattern creates a reference to a reference --> $DIR/needless_borrow_pat.rs:117:21 | LL | if let Some(ref x) = Some(&String::new()); - | ^^^^^ help: try this: `x` + | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference --> $DIR/needless_borrow_pat.rs:125:12 @@ -83,7 +83,7 @@ error: this pattern creates a reference to a reference LL | fn f2<'a>(&ref x: &&'a String) -> &'a String { | ^^^^^ | -help: try this +help: try | LL ~ fn f2<'a>(&x: &&'a String) -> &'a String { LL | let _: &String = x; @@ -94,7 +94,7 @@ error: this pattern creates a reference to a reference --> $DIR/needless_borrow_pat.rs:132:11 | LL | fn f(&ref x: &&String) { - | ^^^^^ help: try this: `x` + | ^^^^^ help: try: `x` error: this pattern creates a reference to a reference --> $DIR/needless_borrow_pat.rs:140:11 @@ -102,7 +102,7 @@ error: this pattern creates a reference to a reference LL | fn f(&ref x: &&String) { | ^^^^^ | -help: try this +help: try | LL ~ fn f(&x: &&String) { LL ~ let _: &String = x; diff --git a/tests/ui/needless_borrowed_ref.fixed b/tests/ui/needless_borrowed_ref.fixed index 0c47ceb7b679..59a38425b068 100644 --- a/tests/ui/needless_borrowed_ref.fixed +++ b/tests/ui/needless_borrowed_ref.fixed @@ -1,11 +1,12 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_borrowed_reference)] #![allow( unused, irrefutable_let_patterns, non_shorthand_field_patterns, - clippy::needless_borrow + clippy::needless_borrow, + clippy::needless_if )] fn main() {} diff --git a/tests/ui/needless_borrowed_ref.rs b/tests/ui/needless_borrowed_ref.rs index f883bb0c8891..e48b19cb19db 100644 --- a/tests/ui/needless_borrowed_ref.rs +++ b/tests/ui/needless_borrowed_ref.rs @@ -1,11 +1,12 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_borrowed_reference)] #![allow( unused, irrefutable_let_patterns, non_shorthand_field_patterns, - clippy::needless_borrow + clippy::needless_borrow, + clippy::needless_if )] fn main() {} diff --git a/tests/ui/needless_borrowed_ref.stderr b/tests/ui/needless_borrowed_ref.stderr index 8d0f0c258dd2..35497a01ec22 100644 --- a/tests/ui/needless_borrowed_ref.stderr +++ b/tests/ui/needless_borrowed_ref.stderr @@ -1,5 +1,5 @@ error: this pattern takes a reference on something that is being dereferenced - --> $DIR/needless_borrowed_ref.rs:31:34 + --> $DIR/needless_borrowed_ref.rs:32:34 | LL | let _ = v.iter_mut().filter(|&ref a| a.is_empty()); | ^^^^^^ @@ -12,7 +12,7 @@ LL + let _ = v.iter_mut().filter(|a| a.is_empty()); | error: this pattern takes a reference on something that is being dereferenced - --> $DIR/needless_borrowed_ref.rs:35:17 + --> $DIR/needless_borrowed_ref.rs:36:17 | LL | if let Some(&ref v) = thingy {} | ^^^^^^ @@ -24,7 +24,7 @@ LL + if let Some(v) = thingy {} | error: this pattern takes a reference on something that is being dereferenced - --> $DIR/needless_borrowed_ref.rs:37:14 + --> $DIR/needless_borrowed_ref.rs:38:14 | LL | if let &[&ref a, ref b] = slice_of_refs {} | ^^^^^^ @@ -36,7 +36,7 @@ LL + if let &[a, ref b] = slice_of_refs {} | error: dereferencing a slice pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:39:9 + --> $DIR/needless_borrowed_ref.rs:40:9 | LL | let &[ref a, ..] = &array; | ^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL + let [a, ..] = &array; | error: dereferencing a slice pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:40:9 + --> $DIR/needless_borrowed_ref.rs:41:9 | LL | let &[ref a, ref b, ..] = &array; | ^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL + let [a, b, ..] = &array; | error: dereferencing a slice pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:42:12 + --> $DIR/needless_borrowed_ref.rs:43:12 | LL | if let &[ref a, ref b] = slice {} | ^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL + if let [a, b] = slice {} | error: dereferencing a slice pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:43:12 + --> $DIR/needless_borrowed_ref.rs:44:12 | LL | if let &[ref a, ref b] = &vec[..] {} | ^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL + if let [a, b] = &vec[..] {} | error: dereferencing a slice pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:45:12 + --> $DIR/needless_borrowed_ref.rs:46:12 | LL | if let &[ref a, ref b, ..] = slice {} | ^^^^^^^^^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL + if let [a, b, ..] = slice {} | error: dereferencing a slice pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:46:12 + --> $DIR/needless_borrowed_ref.rs:47:12 | LL | if let &[ref a, .., ref b] = slice {} | ^^^^^^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL + if let [a, .., b] = slice {} | error: dereferencing a slice pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:47:12 + --> $DIR/needless_borrowed_ref.rs:48:12 | LL | if let &[.., ref a, ref b] = slice {} | ^^^^^^^^^^^^^^^^^^^ @@ -120,7 +120,7 @@ LL + if let [.., a, b] = slice {} | error: dereferencing a slice pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:49:12 + --> $DIR/needless_borrowed_ref.rs:50:12 | LL | if let &[ref a, _] = slice {} | ^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL + if let [a, _] = slice {} | error: dereferencing a tuple pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:51:12 + --> $DIR/needless_borrowed_ref.rs:52:12 | LL | if let &(ref a, ref b, ref c) = &tuple {} | ^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL + if let (a, b, c) = &tuple {} | error: dereferencing a tuple pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:52:12 + --> $DIR/needless_borrowed_ref.rs:53:12 | LL | if let &(ref a, _, ref c) = &tuple {} | ^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ LL + if let (a, _, c) = &tuple {} | error: dereferencing a tuple pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:53:12 + --> $DIR/needless_borrowed_ref.rs:54:12 | LL | if let &(ref a, ..) = &tuple {} | ^^^^^^^^^^^^ @@ -168,7 +168,7 @@ LL + if let (a, ..) = &tuple {} | error: dereferencing a tuple pattern where every element takes a reference - --> $DIR/needless_borrowed_ref.rs:55:12 + --> $DIR/needless_borrowed_ref.rs:56:12 | LL | if let &TupleStruct(ref a, ..) = &tuple_struct {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -180,7 +180,7 @@ LL + if let TupleStruct(a, ..) = &tuple_struct {} | error: dereferencing a struct pattern where every field's pattern takes a reference - --> $DIR/needless_borrowed_ref.rs:57:12 + --> $DIR/needless_borrowed_ref.rs:58:12 | LL | if let &Struct { | ____________^ @@ -199,7 +199,7 @@ LL ~ c: renamed, | error: dereferencing a struct pattern where every field's pattern takes a reference - --> $DIR/needless_borrowed_ref.rs:64:12 + --> $DIR/needless_borrowed_ref.rs:65:12 | LL | if let &Struct { ref a, b: _, .. } = &s {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed index 2659ad384885..0a459fbb8ea2 100644 --- a/tests/ui/needless_collect.fixed +++ b/tests/ui/needless_collect.fixed @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix -#![allow(unused, clippy::suspicious_map, clippy::iter_count)] +#![allow(unused, clippy::needless_if, clippy::suspicious_map, clippy::iter_count)] use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList}; @@ -62,4 +62,30 @@ fn main() { let _ = sample.iter().next().is_none(); let _ = sample.iter().any(|x| x == &0); + + #[allow(clippy::double_parens)] + { + Vec::::new().extend((0..10)); + foo((0..10)); + bar((0..10).collect::>(), (0..10)); + baz((0..10), (), ('a'..='z')) + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 974900b50 (Split `for_loops` tests) + + let values = [1, 2, 3, 4]; + let mut out = vec![]; + values.iter().cloned().map(|x| out.push(x)).collect::>(); + let _y = values.iter().cloned().map(|x| out.push(x)).collect::>(); // this is fine +<<<<<<< HEAD +======= +>>>>>>> 84f89f30e (enhance `needless_collect`) +======= +>>>>>>> 974900b50 (Split `for_loops` tests) } + +fn foo(_: impl IntoIterator) {} +fn bar>(_: Vec, _: I) {} +fn baz>(_: I, _: (), _: impl IntoIterator) {} diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs index 535ec82982b1..674870903a3a 100644 --- a/tests/ui/needless_collect.rs +++ b/tests/ui/needless_collect.rs @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix -#![allow(unused, clippy::suspicious_map, clippy::iter_count)] +#![allow(unused, clippy::needless_if, clippy::suspicious_map, clippy::iter_count)] use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList}; @@ -62,4 +62,30 @@ fn main() { let _ = sample.iter().collect::>().is_empty(); let _ = sample.iter().collect::>().contains(&&0); + + #[allow(clippy::double_parens)] + { + Vec::::new().extend((0..10).collect::>()); + foo((0..10).collect::>()); + bar((0..10).collect::>(), (0..10).collect::>()); + baz((0..10), (), ('a'..='z').collect::>()) + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 974900b50 (Split `for_loops` tests) + + let values = [1, 2, 3, 4]; + let mut out = vec![]; + values.iter().cloned().map(|x| out.push(x)).collect::>(); + let _y = values.iter().cloned().map(|x| out.push(x)).collect::>(); // this is fine +<<<<<<< HEAD +======= +>>>>>>> 84f89f30e (enhance `needless_collect`) +======= +>>>>>>> 974900b50 (Split `for_loops` tests) } + +fn foo(_: impl IntoIterator) {} +fn bar>(_: Vec, _: I) {} +fn baz>(_: I, _: (), _: impl IntoIterator) {} diff --git a/tests/ui/needless_collect.stderr b/tests/ui/needless_collect.stderr index 584d2a1d8356..ad22a7b057e0 100644 --- a/tests/ui/needless_collect.stderr +++ b/tests/ui/needless_collect.stderr @@ -90,5 +90,29 @@ error: avoid using `collect()` when not needed LL | let _ = sample.iter().collect::>().contains(&&0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)` -error: aborting due to 15 previous errors +error: avoid using `collect()` when not needed + --> $DIR/needless_collect.rs:68:40 + | +LL | Vec::::new().extend((0..10).collect::>()); + | ^^^^^^^^^^^^^^^^^^^^ help: remove this call + +error: avoid using `collect()` when not needed + --> $DIR/needless_collect.rs:69:20 + | +LL | foo((0..10).collect::>()); + | ^^^^^^^^^^^^^^^^^^^^ help: remove this call + +error: avoid using `collect()` when not needed + --> $DIR/needless_collect.rs:70:49 + | +LL | bar((0..10).collect::>(), (0..10).collect::>()); + | ^^^^^^^^^^^^^^^^^^^^ help: remove this call + +error: avoid using `collect()` when not needed + --> $DIR/needless_collect.rs:71:37 + | +LL | baz((0..10), (), ('a'..='z').collect::>()) + | ^^^^^^^^^^^^^^^^^^^^ help: remove this call + +error: aborting due to 19 previous errors diff --git a/tests/ui/needless_collect_indirect.rs b/tests/ui/needless_collect_indirect.rs index fe4209e99b2f..12ed75e60a22 100644 --- a/tests/ui/needless_collect_indirect.rs +++ b/tests/ui/needless_collect_indirect.rs @@ -1,4 +1,12 @@ -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::uninlined_format_args, clippy::useless_vec)] +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::needless_if, clippy::uninlined_format_args)] +======= +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +#![allow(clippy::needless_if, clippy::uninlined_format_args)] +>>>>>>> 26f50395b (Add `needless_if` lint) #![warn(clippy::needless_collect)] use std::collections::{BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; diff --git a/tests/ui/needless_collect_indirect.stderr b/tests/ui/needless_collect_indirect.stderr index 790d725907f3..8f84c5596889 100644 --- a/tests/ui/needless_collect_indirect.stderr +++ b/tests/ui/needless_collect_indirect.stderr @@ -1,5 +1,5 @@ error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:8:39 + --> $DIR/needless_collect_indirect.rs:9:39 | LL | let indirect_iter = sample.iter().collect::>(); | ^^^^^^^ @@ -14,7 +14,7 @@ LL ~ sample.iter().map(|x| (x, x + 1)).collect::>(); | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:10:38 + --> $DIR/needless_collect_indirect.rs:11:38 | LL | let indirect_len = sample.iter().collect::>(); | ^^^^^^^ @@ -28,7 +28,7 @@ LL ~ sample.iter().count(); | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:12:40 + --> $DIR/needless_collect_indirect.rs:13:40 | LL | let indirect_empty = sample.iter().collect::>(); | ^^^^^^^ @@ -42,7 +42,7 @@ LL ~ sample.iter().next().is_none(); | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:14:43 + --> $DIR/needless_collect_indirect.rs:15:43 | LL | let indirect_contains = sample.iter().collect::>(); | ^^^^^^^ @@ -56,7 +56,7 @@ LL ~ sample.iter().any(|x| x == &5); | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:26:48 + --> $DIR/needless_collect_indirect.rs:27:48 | LL | let non_copy_contains = sample.into_iter().collect::>(); | ^^^^^^^ @@ -70,7 +70,7 @@ LL ~ sample.into_iter().any(|x| x == a); | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:55:51 + --> $DIR/needless_collect_indirect.rs:56:51 | LL | let buffer: Vec<&str> = string.split('/').collect(); | ^^^^^^^ @@ -84,7 +84,7 @@ LL ~ string.split('/').count() | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:60:55 + --> $DIR/needless_collect_indirect.rs:61:55 | LL | let indirect_len: VecDeque<_> = sample.iter().collect(); | ^^^^^^^ @@ -98,7 +98,7 @@ LL ~ sample.iter().count() | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:65:57 + --> $DIR/needless_collect_indirect.rs:66:57 | LL | let indirect_len: LinkedList<_> = sample.iter().collect(); | ^^^^^^^ @@ -112,7 +112,7 @@ LL ~ sample.iter().count() | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:70:57 + --> $DIR/needless_collect_indirect.rs:71:57 | LL | let indirect_len: BinaryHeap<_> = sample.iter().collect(); | ^^^^^^^ @@ -126,7 +126,7 @@ LL ~ sample.iter().count() | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:130:59 + --> $DIR/needless_collect_indirect.rs:131:59 | LL | let y: Vec = vec.iter().map(|k| k * k).collect(); | ^^^^^^^ @@ -143,7 +143,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == i); | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:155:59 + --> $DIR/needless_collect_indirect.rs:156:59 | LL | let y: Vec = vec.iter().map(|k| k * k).collect(); | ^^^^^^^ @@ -160,7 +160,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == n); | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:184:63 + --> $DIR/needless_collect_indirect.rs:185:63 | LL | let y: Vec = vec.iter().map(|k| k * k).collect(); | ^^^^^^^ @@ -177,7 +177,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == n); | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:220:59 + --> $DIR/needless_collect_indirect.rs:221:59 | LL | let y: Vec = vec.iter().map(|k| k * k).collect(); | ^^^^^^^ @@ -195,7 +195,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == n); | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:245:26 + --> $DIR/needless_collect_indirect.rs:246:26 | LL | let w = v.iter().collect::>(); | ^^^^^^^ @@ -211,7 +211,7 @@ LL ~ for _ in 0..v.iter().count() { | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:267:30 + --> $DIR/needless_collect_indirect.rs:268:30 | LL | let mut w = v.iter().collect::>(); | ^^^^^^^ @@ -227,7 +227,7 @@ LL ~ while 1 == v.iter().count() { | error: avoid using `collect()` when not needed - --> $DIR/needless_collect_indirect.rs:289:30 + --> $DIR/needless_collect_indirect.rs:290:30 | LL | let mut w = v.iter().collect::>(); | ^^^^^^^ diff --git a/tests/ui/needless_else.fixed b/tests/ui/needless_else.fixed new file mode 100644 index 000000000000..9d62d477d8cf --- /dev/null +++ b/tests/ui/needless_else.fixed @@ -0,0 +1,75 @@ +//@run-rustfix +#![allow(unused)] +#![warn(clippy::needless_else)] +#![allow(clippy::suspicious_else_formatting)] + +macro_rules! mac { + ($test:expr) => { + if $test { + println!("Test successful!"); + } else { + } + }; +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) +macro_rules! empty_expansion { + () => {}; +} + +<<<<<<< HEAD +======= +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) +fn main() { + let b = std::hint::black_box(true); + + if b { + println!("Foobar"); + } + + if b { + println!("Foobar"); + } else { + // Do not lint because this comment might be important + } + + if b { + println!("Foobar"); + } else + /* Do not lint because this comment might be important */ + { + } + + // Do not lint because of the expression + let _ = if b { 1 } else { 2 }; + + // Do not lint because inside a macro + mac!(b); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) + + if b { + println!("Foobar"); + } else { + #[cfg(foo)] + "Do not lint cfg'd out code" + } + + if b { + println!("Foobar"); + } else { + empty_expansion!(); + } +<<<<<<< HEAD +======= +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) +} diff --git a/tests/ui/needless_else.rs b/tests/ui/needless_else.rs new file mode 100644 index 000000000000..a8ff2203d246 --- /dev/null +++ b/tests/ui/needless_else.rs @@ -0,0 +1,76 @@ +//@run-rustfix +#![allow(unused)] +#![warn(clippy::needless_else)] +#![allow(clippy::suspicious_else_formatting)] + +macro_rules! mac { + ($test:expr) => { + if $test { + println!("Test successful!"); + } else { + } + }; +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) +macro_rules! empty_expansion { + () => {}; +} + +<<<<<<< HEAD +======= +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) +fn main() { + let b = std::hint::black_box(true); + + if b { + println!("Foobar"); + } else { + } + + if b { + println!("Foobar"); + } else { + // Do not lint because this comment might be important + } + + if b { + println!("Foobar"); + } else + /* Do not lint because this comment might be important */ + { + } + + // Do not lint because of the expression + let _ = if b { 1 } else { 2 }; + + // Do not lint because inside a macro + mac!(b); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) + + if b { + println!("Foobar"); + } else { + #[cfg(foo)] + "Do not lint cfg'd out code" + } + + if b { + println!("Foobar"); + } else { + empty_expansion!(); + } +<<<<<<< HEAD +======= +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) +} diff --git a/tests/ui/needless_else.stderr b/tests/ui/needless_else.stderr new file mode 100644 index 000000000000..bd5775a7b9a7 --- /dev/null +++ b/tests/ui/needless_else.stderr @@ -0,0 +1,24 @@ +<<<<<<< HEAD +error: this else branch is empty +<<<<<<< HEAD +<<<<<<< HEAD +======= +error: this `else` branch is empty +>>>>>>> 885a18207 (Fix typos) + --> $DIR/needless_else.rs:24:7 +======= + --> $DIR/needless_else.rs:20:7 +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= + --> $DIR/needless_else.rs:24:7 +>>>>>>> 021b7398e (Ignore #[cfg]'d out code in needless_else) + | +LL | } else { + | _______^ +LL | | } + | |_____^ help: you can remove it + | + = note: `-D clippy::needless-else` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/tests/ui/needless_for_each_fixable.fixed b/tests/ui/needless_for_each_fixable.fixed index 09e671b88e1a..92572942bc0d 100644 --- a/tests/ui/needless_for_each_fixable.fixed +++ b/tests/ui/needless_for_each_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_for_each)] #![allow(unused)] #![allow( @@ -110,7 +110,7 @@ fn should_not_lint() { }), } - // `for_each` is in a let bingind. + // `for_each` is in a let binding. let _ = v.iter().for_each(|elem| { acc += elem; }); diff --git a/tests/ui/needless_for_each_fixable.rs b/tests/ui/needless_for_each_fixable.rs index abb4045b9197..95acbdff8cc2 100644 --- a/tests/ui/needless_for_each_fixable.rs +++ b/tests/ui/needless_for_each_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_for_each)] #![allow(unused)] #![allow( @@ -110,7 +110,7 @@ fn should_not_lint() { }), } - // `for_each` is in a let bingind. + // `for_each` is in a let binding. let _ = v.iter().for_each(|elem| { acc += elem; }); diff --git a/tests/ui/needless_if.fixed b/tests/ui/needless_if.fixed new file mode 100644 index 000000000000..11ac42d71d41 --- /dev/null +++ b/tests/ui/needless_if.fixed @@ -0,0 +1,210 @@ +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5bd97ac17 (Update tests) +//@aux-build:proc_macros.rs:proc-macro +#![feature(let_chains)] +======= +//@aux-build:proc_macros.rs +<<<<<<< HEAD +>>>>>>> 26f50395b (Add `needless_if` lint) +======= +#![feature(let_chains)] +>>>>>>> 59bca098f (don't lint on `if let`) +#![allow( + clippy::blocks_in_if_conditions, + clippy::if_same_then_else, + clippy::ifs_same_cond, +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + clippy::let_unit_value, + clippy::needless_else, + clippy::no_effect, + clippy::nonminimal_bool, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::short_circuit_statement, + clippy::unnecessary_operation, +======= + clippy::needless_else, + clippy::no_effect, +>>>>>>> 26f50395b (Add `needless_if` lint) +======= +>>>>>>> 59bca098f (don't lint on `if let`) +======= + clippy::short_circuit_statement, + clippy::unnecessary_operation, +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + unused +)] +#![warn(clippy::needless_if)] + +extern crate proc_macros; +use proc_macros::{external, with_span}; + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +fn maybe_side_effect() -> bool { + true +} + +fn main() { + // Lint + + // Do not remove the condition + maybe_side_effect(); +======= +fn main() { + // Lint + (true); +>>>>>>> 26f50395b (Add `needless_if` lint) +======= +fn no_side_effects() -> bool { + true +} + +fn has_side_effects(a: &mut u32) -> bool { + *a = 1; +======= +fn maybe_side_effect() -> bool { +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + true +} + +fn main() { + // Lint + + // Do not remove the condition +<<<<<<< HEAD + no_side_effects(); + let mut x = 0; + has_side_effects(&mut x); + assert_eq!(x, 1); +>>>>>>> 59bca098f (don't lint on `if let`) +======= + maybe_side_effect(); +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + // Do not lint + if (true) { + } else { + } +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + ({ + return; + }); +======= +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + { + return; + }; +>>>>>>> 59bca098f (don't lint on `if let`) +======= + ({ + return; + }); +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + // Do not lint if `else if` is present + if (true) { + } else if (true) { + } +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + // Do not lint `if let` or let chains + if let true = true {} + if let true = true && true {} + if true && let true = true {} + // Can lint nested `if let`s + ({ + if let true = true && true { true } else { false } + } && true); +======= + // Ensure clippy does not bork this up, other cases should be added + { + return; + }; +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + // Do not lint if any `let` is present + if let true = true {} + if let true = true && true {} + if true && let true = true {} +<<<<<<< HEAD + if { if let true = true && true { true } else { false } } && true {} +>>>>>>> 59bca098f (don't lint on `if let`) +======= + if { + if let true = true && true { true } else { false } + } && true + {} +>>>>>>> d989f432a (Update needless_if.fixed) +======= + // Do not lint `if let` or let chains + if let true = true {} + if let true = true && true {} + if true && let true = true {} + // Can lint nested `if let`s + ({ + if let true = true && true { true } else { false } + } && true); +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + external! { if (true) {} } + with_span! { + span + if (true) {} + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + + if true { + // comment + } + + if true { + #[cfg(any())] + foo; + } + + macro_rules! empty_expansion { + () => {}; + } + + if true { + empty_expansion!(); + } + + macro_rules! empty_repetition { + ($($t:tt)*) => { + if true { + $($t)* + } + } + } + + empty_repetition!(); + + // Must be placed into an expression context to not be interpreted as a block + ({ maybe_side_effect() }); + // Would be a block followed by `&&true` - a double reference to `true` + ({ maybe_side_effect() } && true); + + // Don't leave trailing attributes + #[allow(unused)] + true; + + let () = if maybe_side_effect() {}; +<<<<<<< HEAD +======= +>>>>>>> 26f50395b (Add `needless_if` lint) +======= +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) +} diff --git a/tests/ui/needless_if.rs b/tests/ui/needless_if.rs new file mode 100644 index 000000000000..68c351d07510 --- /dev/null +++ b/tests/ui/needless_if.rs @@ -0,0 +1,191 @@ +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5bd97ac17 (Update tests) +//@aux-build:proc_macros.rs:proc-macro +#![feature(let_chains)] +======= +//@aux-build:proc_macros.rs +<<<<<<< HEAD +>>>>>>> 26f50395b (Add `needless_if` lint) +======= +#![feature(let_chains)] +>>>>>>> 59bca098f (don't lint on `if let`) +#![allow( + clippy::blocks_in_if_conditions, + clippy::if_same_then_else, + clippy::ifs_same_cond, +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + clippy::let_unit_value, + clippy::needless_else, + clippy::no_effect, + clippy::nonminimal_bool, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::short_circuit_statement, + clippy::unnecessary_operation, +======= + clippy::needless_else, + clippy::no_effect, +>>>>>>> 26f50395b (Add `needless_if` lint) +======= +>>>>>>> 59bca098f (don't lint on `if let`) +======= + clippy::short_circuit_statement, + clippy::unnecessary_operation, +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + unused +)] +#![warn(clippy::needless_if)] + +extern crate proc_macros; +use proc_macros::{external, with_span}; + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +fn maybe_side_effect() -> bool { +======= +fn no_side_effects() -> bool { + true +} + +fn has_side_effects(a: &mut u32) -> bool { + *a = 1; +>>>>>>> 59bca098f (don't lint on `if let`) +======= +fn maybe_side_effect() -> bool { +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + true +} + +fn main() { + // Lint + if (true) {} + // Do not remove the condition +<<<<<<< HEAD +<<<<<<< HEAD + if maybe_side_effect() {} +======= +fn main() { + // Lint + if (true) {} +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + if no_side_effects() {} + let mut x = 0; + if has_side_effects(&mut x) {} + assert_eq!(x, 1); +>>>>>>> 59bca098f (don't lint on `if let`) +======= + if maybe_side_effect() {} +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + // Do not lint + if (true) { + } else { + } +<<<<<<< HEAD +<<<<<<< HEAD + if { + return; + } {} +======= +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + if { + return; + } {} +>>>>>>> 59bca098f (don't lint on `if let`) + // Do not lint if `else if` is present + if (true) { + } else if (true) { + } +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + // Do not lint `if let` or let chains + if let true = true {} + if let true = true && true {} + if true && let true = true {} + // Can lint nested `if let`s + if { + if let true = true && true { true } else { false } + } && true + {} +======= + // Ensure clippy does not bork this up, other cases should be added + if { + return; + } {} +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + // Do not lint if any `let` is present +======= + // Do not lint `if let` or let chains +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + if let true = true {} + if let true = true && true {} + if true && let true = true {} + // Can lint nested `if let`s + if { + if let true = true && true { true } else { false } + } && true + {} +>>>>>>> 59bca098f (don't lint on `if let`) + external! { if (true) {} } + with_span! { + span + if (true) {} + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + + if true { + // comment + } + + if true { + #[cfg(any())] + foo; + } + + macro_rules! empty_expansion { + () => {}; + } + + if true { + empty_expansion!(); + } + + macro_rules! empty_repetition { + ($($t:tt)*) => { + if true { + $($t)* + } + } + } + + empty_repetition!(); + + // Must be placed into an expression context to not be interpreted as a block + if { maybe_side_effect() } {} + // Would be a block followed by `&&true` - a double reference to `true` + if { maybe_side_effect() } && true {} + + // Don't leave trailing attributes + #[allow(unused)] + if true {} + + let () = if maybe_side_effect() {}; +<<<<<<< HEAD +======= +>>>>>>> 26f50395b (Add `needless_if` lint) +======= +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) +} diff --git a/tests/ui/needless_if.stderr b/tests/ui/needless_if.stderr new file mode 100644 index 000000000000..4aca5a7ed161 --- /dev/null +++ b/tests/ui/needless_if.stderr @@ -0,0 +1,170 @@ +<<<<<<< HEAD +<<<<<<< HEAD +error: this `if` branch is empty + --> $DIR/needless_if.rs:27:5 + | +LL | if (true) {} + | ^^^^^^^^^^^^ help: you can remove it + | + = note: `-D clippy::needless-if` implied by `-D warnings` + +error: this `if` branch is empty +<<<<<<< HEAD + --> $DIR/needless_if.rs:30:5 +<<<<<<< HEAD +======= + --> $DIR/needless_if.rs:29:5 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) + | +LL | if maybe_side_effect() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `maybe_side_effect();` + +error: this `if` branch is empty +<<<<<<< HEAD + --> $DIR/needless_if.rs:35:5 +======= +error: this if branch is empty + --> $DIR/needless_if.rs:19:5 +======= +error: this `if` branch is empty + --> $DIR/needless_if.rs:30:5 +>>>>>>> 59bca098f (don't lint on `if let`) + | +LL | if (true) {} + | ^^^^^^^^^^^^ help: you can remove it + | + = note: `-D clippy::needless-if` implied by `-D warnings` + +<<<<<<< HEAD +error: this if branch is empty + --> $DIR/needless_if.rs:29:5 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= +error: this `if` branch is empty + --> $DIR/needless_if.rs:32:5 +======= +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + | +LL | if maybe_side_effect() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `maybe_side_effect();` + +error: this `if` branch is empty +<<<<<<< HEAD + --> $DIR/needless_if.rs:34:5 + | +LL | if has_side_effects(&mut x) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `has_side_effects(&mut x);` + +error: this `if` branch is empty + --> $DIR/needless_if.rs:40:5 +>>>>>>> 59bca098f (don't lint on `if let`) +======= + --> $DIR/needless_if.rs:35:5 +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) +======= + --> $DIR/needless_if.rs:34:5 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) + | +LL | / if { +LL | | return; +LL | | } {} + | |________^ + | +help: you can remove it + | +<<<<<<< HEAD +<<<<<<< HEAD +LL ~ ({ +LL + return; +LL + }); + | + +error: this `if` branch is empty + --> $DIR/needless_if.rs:46:5 + | +LL | / if { +LL | | if let true = true && true { true } else { false } +LL | | } && true +LL | | {} + | |______^ + | +help: you can remove it + | +LL ~ ({ +LL + if let true = true && true { true } else { false } +LL + } && true); + | + +error: this `if` branch is empty + --> $DIR/needless_if.rs:84:5 + | +LL | if { maybe_side_effect() } {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() });` + +error: this `if` branch is empty + --> $DIR/needless_if.rs:86:5 + | +LL | if { maybe_side_effect() } && true {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() } && true);` + +error: this `if` branch is empty + --> $DIR/needless_if.rs:90:5 + | +LL | if true {} + | ^^^^^^^^^^ help: you can remove it: `true;` + +error: aborting due to 7 previous errors +======= +LL ~ { +======= +LL ~ ({ +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) +LL + return; +LL + }); + | + +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 2 previous errors +>>>>>>> 26f50395b (Add `needless_if` lint) +======= +error: aborting due to 4 previous errors +>>>>>>> 59bca098f (don't lint on `if let`) +======= +error: this `if` branch is empty + --> $DIR/needless_if.rs:47:5 + | +LL | / if { +LL | | if let true = true && true { true } else { false } +LL | | } && true +LL | | {} + | |______^ + | +help: you can remove it + | +LL ~ ({ +LL + if let true = true && true { true } else { false } +LL + } && true); + | + +error: this `if` branch is empty + --> $DIR/needless_if.rs:85:5 + | +LL | if { maybe_side_effect() } {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() });` + +error: this `if` branch is empty + --> $DIR/needless_if.rs:87:5 + | +LL | if { maybe_side_effect() } && true {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() } && true);` + +error: this `if` branch is empty + --> $DIR/needless_if.rs:91:5 + | +LL | if true {} + | ^^^^^^^^^^ help: you can remove it: `true;` + +error: aborting due to 7 previous errors +>>>>>>> 5e20a572e (Don't lint non-statement/faux empty `needless_if`s) + diff --git a/tests/ui/needless_late_init.fixed b/tests/ui/needless_late_init.fixed index 86d899bb46c3..6b40595a8946 100644 --- a/tests/ui/needless_late_init.fixed +++ b/tests/ui/needless_late_init.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(let_chains)] #![allow(unused)] #![allow( @@ -8,7 +12,8 @@ clippy::let_and_return, clippy::let_unit_value, clippy::nonminimal_bool, - clippy::uninlined_format_args + clippy::uninlined_format_args, + clippy::useless_vec )] extern crate proc_macros; diff --git a/tests/ui/needless_late_init.rs b/tests/ui/needless_late_init.rs index 969afb38edf2..3a3f5223d18d 100644 --- a/tests/ui/needless_late_init.rs +++ b/tests/ui/needless_late_init.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(let_chains)] #![allow(unused)] #![allow( @@ -8,7 +12,8 @@ clippy::let_and_return, clippy::let_unit_value, clippy::nonminimal_bool, - clippy::uninlined_format_args + clippy::uninlined_format_args, + clippy::useless_vec )] extern crate proc_macros; diff --git a/tests/ui/needless_late_init.stderr b/tests/ui/needless_late_init.stderr index eff782f8bf10..78ba8e11c575 100644 --- a/tests/ui/needless_late_init.stderr +++ b/tests/ui/needless_late_init.stderr @@ -1,5 +1,5 @@ error: unneeded late initialization - --> $DIR/needless_late_init.rs:27:5 + --> $DIR/needless_late_init.rs:28:5 | LL | let a; | ^^^^^^ created here @@ -13,7 +13,7 @@ LL | let a = "zero"; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:30:5 + --> $DIR/needless_late_init.rs:31:5 | LL | let b; | ^^^^^^ created here @@ -27,7 +27,7 @@ LL | let b = 1; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:31:5 + --> $DIR/needless_late_init.rs:32:5 | LL | let c; | ^^^^^^ created here @@ -41,7 +41,7 @@ LL | let c = 2; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:35:5 + --> $DIR/needless_late_init.rs:36:5 | LL | let d: usize; | ^^^^^^^^^^^^^ created here @@ -54,7 +54,7 @@ LL | let d: usize = 1; | ~~~~~~~~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:38:5 + --> $DIR/needless_late_init.rs:39:5 | LL | let e; | ^^^^^^ created here @@ -67,7 +67,7 @@ LL | let e = format!("{}", d); | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:43:5 + --> $DIR/needless_late_init.rs:44:5 | LL | let a; | ^^^^^^ @@ -88,7 +88,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:52:5 + --> $DIR/needless_late_init.rs:53:5 | LL | let b; | ^^^^^^ @@ -109,7 +109,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:59:5 + --> $DIR/needless_late_init.rs:60:5 | LL | let d; | ^^^^^^ @@ -130,7 +130,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:67:5 + --> $DIR/needless_late_init.rs:68:5 | LL | let e; | ^^^^^^ @@ -151,7 +151,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:74:5 + --> $DIR/needless_late_init.rs:75:5 | LL | let f; | ^^^^^^ @@ -167,7 +167,7 @@ LL + 1 => "three", | error: unneeded late initialization - --> $DIR/needless_late_init.rs:80:5 + --> $DIR/needless_late_init.rs:81:5 | LL | let g: usize; | ^^^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:88:5 + --> $DIR/needless_late_init.rs:89:5 | LL | let x; | ^^^^^^ created here @@ -201,7 +201,7 @@ LL | let x = 1; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:92:5 + --> $DIR/needless_late_init.rs:93:5 | LL | let x; | ^^^^^^ created here @@ -215,7 +215,7 @@ LL | let x = SignificantDrop; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:96:5 + --> $DIR/needless_late_init.rs:97:5 | LL | let x; | ^^^^^^ created here @@ -229,7 +229,7 @@ LL | let x = SignificantDrop; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:115:5 + --> $DIR/needless_late_init.rs:116:5 | LL | let a; | ^^^^^^ @@ -250,7 +250,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:132:5 + --> $DIR/needless_late_init.rs:133:5 | LL | let a; | ^^^^^^ diff --git a/tests/ui/needless_lifetimes.fixed b/tests/ui/needless_lifetimes.fixed index e6ead69d148e..471003ff4259 100644 --- a/tests/ui/needless_lifetimes.fixed +++ b/tests/ui/needless_lifetimes.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::needless_lifetimes)] #![allow( diff --git a/tests/ui/needless_lifetimes.rs b/tests/ui/needless_lifetimes.rs index 06eb430506f9..32b4a49b8768 100644 --- a/tests/ui/needless_lifetimes.rs +++ b/tests/ui/needless_lifetimes.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::needless_lifetimes)] #![allow( diff --git a/tests/ui/needless_lifetimes.stderr b/tests/ui/needless_lifetimes.stderr index 86acc4e00469..0da67b600a3f 100644 --- a/tests/ui/needless_lifetimes.stderr +++ b/tests/ui/needless_lifetimes.stderr @@ -1,8 +1,8 @@ error: the following explicit lifetimes could be elided: 'a, 'b - --> $DIR/needless_lifetimes.rs:18:1 + --> $DIR/needless_lifetimes.rs:18:23 | LL | fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ ^^ | = note: `-D clippy::needless-lifetimes` implied by `-D warnings` help: elide the lifetimes @@ -12,10 +12,10 @@ LL + fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {} | error: the following explicit lifetimes could be elided: 'a, 'b - --> $DIR/needless_lifetimes.rs:20:1 + --> $DIR/needless_lifetimes.rs:20:24 | LL | fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ ^^ | help: elide the lifetimes | @@ -24,10 +24,10 @@ LL + fn distinct_and_static(_x: &u8, _y: &u8, _z: &'static u8) {} | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:30:1 + --> $DIR/needless_lifetimes.rs:30:15 | LL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -36,10 +36,10 @@ LL + fn in_and_out(x: &u8, _y: u8) -> &u8 { | error: the following explicit lifetimes could be elided: 'b - --> $DIR/needless_lifetimes.rs:42:1 + --> $DIR/needless_lifetimes.rs:42:31 | LL | fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -48,10 +48,10 @@ LL + fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:49:1 + --> $DIR/needless_lifetimes.rs:49:27 | LL | fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -60,10 +60,10 @@ LL + fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 { | error: the following explicit lifetimes could be elided: 'b - --> $DIR/needless_lifetimes.rs:66:1 + --> $DIR/needless_lifetimes.rs:66:26 | LL | fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -72,10 +72,10 @@ LL + fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:73:1 + --> $DIR/needless_lifetimes.rs:73:22 | LL | fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -84,10 +84,10 @@ LL + fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:82:1 + --> $DIR/needless_lifetimes.rs:82:21 | LL | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -96,10 +96,10 @@ LL + fn deep_reference_3(x: &u8, _y: u8) -> Result<&u8, ()> { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:87:1 + --> $DIR/needless_lifetimes.rs:87:28 | LL | fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -108,10 +108,10 @@ LL + fn where_clause_without_lt(x: &u8, _y: u8) -> Result<&u8, ()> | error: the following explicit lifetimes could be elided: 'a, 'b - --> $DIR/needless_lifetimes.rs:99:1 + --> $DIR/needless_lifetimes.rs:99:21 | LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ ^^ | help: elide the lifetimes | @@ -120,10 +120,10 @@ LL + fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {} | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:123:1 + --> $DIR/needless_lifetimes.rs:123:15 | LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -132,10 +132,10 @@ LL + fn fn_bound_2(_m: Lt<'_, I>, _f: F) -> Lt<'_, I> | error: the following explicit lifetimes could be elided: 's - --> $DIR/needless_lifetimes.rs:153:5 + --> $DIR/needless_lifetimes.rs:153:21 | LL | fn self_and_out<'s>(&'s self) -> &'s u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -144,10 +144,10 @@ LL + fn self_and_out(&self) -> &u8 { | error: the following explicit lifetimes could be elided: 't - --> $DIR/needless_lifetimes.rs:160:5 + --> $DIR/needless_lifetimes.rs:160:30 | LL | fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -156,10 +156,10 @@ LL + fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 { | error: the following explicit lifetimes could be elided: 's - --> $DIR/needless_lifetimes.rs:167:5 + --> $DIR/needless_lifetimes.rs:167:26 | LL | fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -168,10 +168,10 @@ LL + fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 { | error: the following explicit lifetimes could be elided: 's, 't - --> $DIR/needless_lifetimes.rs:171:5 + --> $DIR/needless_lifetimes.rs:171:29 | LL | fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ ^^ | help: elide the lifetimes | @@ -180,10 +180,10 @@ LL + fn distinct_self_and_in(&self, _x: &u8) {} | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:190:1 + --> $DIR/needless_lifetimes.rs:190:19 | LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -192,10 +192,10 @@ LL + fn struct_with_lt(_foo: Foo<'_>) -> &str { | error: the following explicit lifetimes could be elided: 'b - --> $DIR/needless_lifetimes.rs:208:1 + --> $DIR/needless_lifetimes.rs:208:25 | LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -204,10 +204,10 @@ LL + fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:216:1 + --> $DIR/needless_lifetimes.rs:216:21 | LL | fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -216,10 +216,10 @@ LL + fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:231:1 + --> $DIR/needless_lifetimes.rs:231:22 | LL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -228,10 +228,10 @@ LL + fn trait_obj_elided2(_arg: &dyn Drop) -> &str { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:237:1 + --> $DIR/needless_lifetimes.rs:237:18 | LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -240,10 +240,10 @@ LL + fn alias_with_lt(_foo: FooAlias<'_>) -> &str { | error: the following explicit lifetimes could be elided: 'b - --> $DIR/needless_lifetimes.rs:255:1 + --> $DIR/needless_lifetimes.rs:255:24 | LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -252,10 +252,10 @@ LL + fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:263:1 + --> $DIR/needless_lifetimes.rs:263:20 | LL | fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -264,10 +264,10 @@ LL + fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:267:1 + --> $DIR/needless_lifetimes.rs:267:30 | LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^ | help: elide the lifetimes | @@ -276,10 +276,10 @@ LL + fn named_input_elided_output(_arg: &str) -> &str { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:275:1 + --> $DIR/needless_lifetimes.rs:275:19 | LL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -288,10 +288,10 @@ LL + fn trait_bound_ok>(_: &u8, _: T) { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:311:1 + --> $DIR/needless_lifetimes.rs:311:24 | LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -300,10 +300,10 @@ LL + fn out_return_type_lts(e: &str) -> Cow<'_> { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:318:9 + --> $DIR/needless_lifetimes.rs:318:24 | LL | fn needless_lt<'a>(x: &'a u8) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -312,10 +312,10 @@ LL + fn needless_lt(x: &u8) {} | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:322:9 + --> $DIR/needless_lifetimes.rs:322:24 | LL | fn needless_lt<'a>(_x: &'a u8) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -324,10 +324,10 @@ LL + fn needless_lt(_x: &u8) {} | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:335:9 + --> $DIR/needless_lifetimes.rs:335:16 | LL | fn baz<'a>(&'a self) -> impl Foo + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -336,10 +336,10 @@ LL + fn baz(&self) -> impl Foo + '_ { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:367:5 + --> $DIR/needless_lifetimes.rs:367:55 | LL | fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -348,10 +348,10 @@ LL + fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(& | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:376:5 + --> $DIR/needless_lifetimes.rs:376:26 | LL | fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -360,10 +360,10 @@ LL + fn generics_elidable &i32>(i: &i32, f: T) -> &i32 { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:388:5 + --> $DIR/needless_lifetimes.rs:388:32 | LL | fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -372,10 +372,10 @@ LL + fn where_clause_elidadable(i: &i32, f: T) -> &i32 | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:403:5 + --> $DIR/needless_lifetimes.rs:403:28 | LL | fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -384,10 +384,10 @@ LL + fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:416:5 + --> $DIR/needless_lifetimes.rs:416:28 | LL | fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -396,10 +396,10 @@ LL + fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:419:5 + --> $DIR/needless_lifetimes.rs:419:28 | LL | fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -408,10 +408,10 @@ LL + fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:441:9 + --> $DIR/needless_lifetimes.rs:441:21 | LL | fn implicit<'a>(&'a self) -> &'a () { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -420,10 +420,10 @@ LL + fn implicit(&self) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:444:9 + --> $DIR/needless_lifetimes.rs:444:25 | LL | fn implicit_mut<'a>(&'a mut self) -> &'a () { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -432,10 +432,10 @@ LL + fn implicit_mut(&mut self) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:455:9 + --> $DIR/needless_lifetimes.rs:455:31 | LL | fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a () { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -444,10 +444,10 @@ LL + fn lifetime_elsewhere(self: Box, here: &()) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:461:9 + --> $DIR/needless_lifetimes.rs:461:21 | LL | fn implicit<'a>(&'a self) -> &'a (); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -456,10 +456,10 @@ LL + fn implicit(&self) -> &(); | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:462:9 + --> $DIR/needless_lifetimes.rs:462:30 | LL | fn implicit_provided<'a>(&'a self) -> &'a () { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -468,10 +468,10 @@ LL + fn implicit_provided(&self) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:471:9 + --> $DIR/needless_lifetimes.rs:471:31 | LL | fn lifetime_elsewhere<'a>(self: Box, here: &'a ()) -> &'a (); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -480,10 +480,10 @@ LL + fn lifetime_elsewhere(self: Box, here: &()) -> &(); | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:472:9 + --> $DIR/needless_lifetimes.rs:472:40 | LL | fn lifetime_elsewhere_provided<'a>(self: Box, here: &'a ()) -> &'a () { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -492,10 +492,10 @@ LL + fn lifetime_elsewhere_provided(self: Box, here: &()) -> &() { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:481:5 + --> $DIR/needless_lifetimes.rs:481:12 | LL | fn foo<'a>(x: &'a u8, y: &'_ u8) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -504,10 +504,10 @@ LL + fn foo(x: &u8, y: &'_ u8) {} | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:483:5 + --> $DIR/needless_lifetimes.rs:483:12 | LL | fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -516,10 +516,10 @@ LL + fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {} | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:490:5 + --> $DIR/needless_lifetimes.rs:490:18 | LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | help: elide the lifetimes | @@ -528,10 +528,10 @@ LL + fn one_input(x: &u8) -> &u8 { | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:495:5 + --> $DIR/needless_lifetimes.rs:495:42 | LL | fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ | help: elide the lifetimes | @@ -540,10 +540,10 @@ LL + fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:511:9 + --> $DIR/needless_lifetimes.rs:511:22 | LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ ^^ ^^ | = note: this error originates in the macro `__inline_mac_mod_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info) help: elide the lifetimes diff --git a/tests/ui/needless_match.fixed b/tests/ui/needless_match.fixed index 7e47406798cf..d8a0400a4f0d 100644 --- a/tests/ui/needless_match.fixed +++ b/tests/ui/needless_match.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_match)] #![allow(clippy::manual_map)] #![allow(dead_code)] diff --git a/tests/ui/needless_match.rs b/tests/ui/needless_match.rs index 809c694bf400..3de9bd6d7a1f 100644 --- a/tests/ui/needless_match.rs +++ b/tests/ui/needless_match.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_match)] #![allow(clippy::manual_map)] #![allow(dead_code)] diff --git a/tests/ui/needless_option_as_deref.fixed b/tests/ui/needless_option_as_deref.fixed index acd22c6bb433..ec981ad97e3d 100644 --- a/tests/ui/needless_option_as_deref.fixed +++ b/tests/ui/needless_option_as_deref.fixed @@ -1,7 +1,8 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::needless_option_as_deref)] +#![allow(clippy::useless_vec)] fn main() { // should lint diff --git a/tests/ui/needless_option_as_deref.rs b/tests/ui/needless_option_as_deref.rs index 61eda5052a21..6360874f6236 100644 --- a/tests/ui/needless_option_as_deref.rs +++ b/tests/ui/needless_option_as_deref.rs @@ -1,7 +1,8 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::needless_option_as_deref)] +#![allow(clippy::useless_vec)] fn main() { // should lint diff --git a/tests/ui/needless_option_as_deref.stderr b/tests/ui/needless_option_as_deref.stderr index bc07db5b38ed..4c0d502a2031 100644 --- a/tests/ui/needless_option_as_deref.stderr +++ b/tests/ui/needless_option_as_deref.stderr @@ -1,22 +1,22 @@ error: derefed type is same as origin - --> $DIR/needless_option_as_deref.rs:8:29 + --> $DIR/needless_option_as_deref.rs:9:29 | LL | let _: Option<&usize> = Some(&1).as_deref(); - | ^^^^^^^^^^^^^^^^^^^ help: try this: `Some(&1)` + | ^^^^^^^^^^^^^^^^^^^ help: try: `Some(&1)` | = note: `-D clippy::needless-option-as-deref` implied by `-D warnings` error: derefed type is same as origin - --> $DIR/needless_option_as_deref.rs:9:33 + --> $DIR/needless_option_as_deref.rs:10:33 | LL | let _: Option<&mut usize> = Some(&mut 1).as_deref_mut(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Some(&mut 1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(&mut 1)` error: derefed type is same as origin - --> $DIR/needless_option_as_deref.rs:13:13 + --> $DIR/needless_option_as_deref.rs:14:13 | LL | let _ = x.as_deref_mut(); - | ^^^^^^^^^^^^^^^^ help: try this: `x` + | ^^^^^^^^^^^^^^^^ help: try: `x` error: aborting due to 3 previous errors diff --git a/tests/ui/needless_option_take.fixed b/tests/ui/needless_option_take.fixed index 29691e81666f..bfc6d20d5a32 100644 --- a/tests/ui/needless_option_take.fixed +++ b/tests/ui/needless_option_take.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix fn main() { println!("Testing non erroneous option_take_on_temporary"); diff --git a/tests/ui/needless_option_take.rs b/tests/ui/needless_option_take.rs index 9f4109eb4635..697eeab42074 100644 --- a/tests/ui/needless_option_take.rs +++ b/tests/ui/needless_option_take.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix fn main() { println!("Testing non erroneous option_take_on_temporary"); diff --git a/tests/ui/needless_parens_on_range_literals.fixed b/tests/ui/needless_parens_on_range_literals.fixed index f11330a8916d..9b98f6ea7f79 100644 --- a/tests/ui/needless_parens_on_range_literals.fixed +++ b/tests/ui/needless_parens_on_range_literals.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// edition:2018 +//@run-rustfix +//@edition:2018 #![warn(clippy::needless_parens_on_range_literals)] #![allow(clippy::almost_complete_range)] diff --git a/tests/ui/needless_parens_on_range_literals.rs b/tests/ui/needless_parens_on_range_literals.rs index 671c0009e23b..088e7b2b98f0 100644 --- a/tests/ui/needless_parens_on_range_literals.rs +++ b/tests/ui/needless_parens_on_range_literals.rs @@ -1,5 +1,5 @@ -// run-rustfix -// edition:2018 +//@run-rustfix +//@edition:2018 #![warn(clippy::needless_parens_on_range_literals)] #![allow(clippy::almost_complete_range)] diff --git a/tests/ui/needless_pass_by_ref_mut.rs b/tests/ui/needless_pass_by_ref_mut.rs new file mode 100644 index 000000000000..5e7280995c60 --- /dev/null +++ b/tests/ui/needless_pass_by_ref_mut.rs @@ -0,0 +1,105 @@ +#![allow(unused)] + +use std::ptr::NonNull; + +// Should only warn for `s`. +fn foo(s: &mut Vec, b: &u32, x: &mut u32) { + *x += *b + s.len() as u32; +} + +// Should not warn. +fn foo2(s: &mut Vec) { + s.push(8); +} + +// Should not warn because we return it. +fn foo3(s: &mut Vec) -> &mut Vec { + s +} + +// Should not warn because `s` is used as mutable. +fn foo4(s: &mut Vec) { + Vec::push(s, 4); +} + +// Should not warn. +fn foo5(s: &mut Vec) { + foo2(s); +} + +// Should warn. +fn foo6(s: &mut Vec) { + non_mut_ref(s); +} + +fn non_mut_ref(_: &Vec) {} + +struct Bar; + +impl Bar { + // Should not warn on `&mut self`. + fn bar(&mut self) {} + + // Should warn about `vec` + fn mushroom(&self, vec: &mut Vec) -> usize { + vec.len() + } + + // Should warn about `vec` (and not `self`). + fn badger(&mut self, vec: &mut Vec) -> usize { + vec.len() + } +} + +trait Babar { + // Should not warn here since it's a trait method. + fn method(arg: &mut u32); +} + +impl Babar for Bar { + // Should not warn here since it's a trait method. + fn method(a: &mut u32) {} +} + +// Should not warn (checking variable aliasing). +fn alias_check(s: &mut Vec) { + let mut alias = s; + let mut alias2 = alias; + let mut alias3 = alias2; + alias3.push(0); +} + +// Should not warn (checking variable aliasing). +fn alias_check2(mut s: &mut Vec) { + let mut alias = &mut s; + alias.push(0); +} + +struct Mut { + ptr: NonNull, +} + +impl Mut { + // Should not warn because `NonNull::from` also accepts `&mut`. + fn new(ptr: &mut T) -> Self { + Mut { + ptr: NonNull::from(ptr), + } + } +} + +// Should not warn. +fn unused(_: &mut u32, _b: &mut u8) {} + +fn main() { + let mut u = 0; + let mut v = vec![0]; + foo(&mut v, &0, &mut u); + foo2(&mut v); + foo3(&mut v); + foo4(&mut v); + foo5(&mut v); + alias_check(&mut v); + alias_check2(&mut v); + println!("{u}"); +} diff --git a/tests/ui/needless_pass_by_ref_mut.stderr b/tests/ui/needless_pass_by_ref_mut.stderr new file mode 100644 index 000000000000..5e9d80bb6c48 --- /dev/null +++ b/tests/ui/needless_pass_by_ref_mut.stderr @@ -0,0 +1,28 @@ +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:6:11 + | +LL | fn foo(s: &mut Vec, b: &u32, x: &mut u32) { + | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | + = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:31:12 + | +LL | fn foo6(s: &mut Vec) { + | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:44:29 + | +LL | fn mushroom(&self, vec: &mut Vec) -> usize { + | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:49:31 + | +LL | fn badger(&mut self, vec: &mut Vec) -> usize { + | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/needless_pass_by_value_proc_macro.rs b/tests/ui/needless_pass_by_value_proc_macro.rs index 78a0e92d1797..c603163c145f 100644 --- a/tests/ui/needless_pass_by_value_proc_macro.rs +++ b/tests/ui/needless_pass_by_value_proc_macro.rs @@ -1,4 +1,3 @@ -#![crate_type = "proc-macro"] #![warn(clippy::needless_pass_by_value)] extern crate proc_macro; diff --git a/tests/ui/needless_pub_self.fixed b/tests/ui/needless_pub_self.fixed new file mode 100644 index 000000000000..0fd8edb10236 --- /dev/null +++ b/tests/ui/needless_pub_self.fixed @@ -0,0 +1,41 @@ +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> 8296a338d (new lints for visibility) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) +#![feature(custom_inner_attributes)] +#![allow(unused)] +#![warn(clippy::needless_pub_self)] +#![no_main] +#![rustfmt::skip] // rustfmt will remove `in`, understandable + // but very annoying for our purposes! + +#[macro_use] +extern crate proc_macros; + + fn a() {} + fn b() {} + +pub fn c() {} +mod a { + pub(in super) fn d() {} + pub(super) fn e() {} + fn f() {} +} + +external! { + pub(self) fn g() {} + pub(in self) fn h() {} +} +with_span! { + span + pub(self) fn i() {} + pub(in self) fn j() {} +} + +// not really anything more to test. just a really simple lint overall diff --git a/tests/ui/needless_pub_self.rs b/tests/ui/needless_pub_self.rs new file mode 100644 index 000000000000..78e4fff87931 --- /dev/null +++ b/tests/ui/needless_pub_self.rs @@ -0,0 +1,41 @@ +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> 8296a338d (new lints for visibility) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) +#![feature(custom_inner_attributes)] +#![allow(unused)] +#![warn(clippy::needless_pub_self)] +#![no_main] +#![rustfmt::skip] // rustfmt will remove `in`, understandable + // but very annoying for our purposes! + +#[macro_use] +extern crate proc_macros; + +pub(self) fn a() {} +pub(in self) fn b() {} + +pub fn c() {} +mod a { + pub(in super) fn d() {} + pub(super) fn e() {} + pub(self) fn f() {} +} + +external! { + pub(self) fn g() {} + pub(in self) fn h() {} +} +with_span! { + span + pub(self) fn i() {} + pub(in self) fn j() {} +} + +// not really anything more to test. just a really simple lint overall diff --git a/tests/ui/needless_pub_self.stderr b/tests/ui/needless_pub_self.stderr new file mode 100644 index 000000000000..3aa2feb5ecd8 --- /dev/null +++ b/tests/ui/needless_pub_self.stderr @@ -0,0 +1,22 @@ +error: unnecessary `pub(self)` + --> $DIR/needless_pub_self.rs:13:1 + | +LL | pub(self) fn a() {} + | ^^^^^^^^^ help: remove it + | + = note: `-D clippy::needless-pub-self` implied by `-D warnings` + +error: unnecessary `pub(in self)` + --> $DIR/needless_pub_self.rs:14:1 + | +LL | pub(in self) fn b() {} + | ^^^^^^^^^^^^ help: remove it + +error: unnecessary `pub(self)` + --> $DIR/needless_pub_self.rs:20:5 + | +LL | pub(self) fn f() {} + | ^^^^^^^^^ help: remove it + +error: aborting due to 3 previous errors + diff --git a/tests/ui/needless_question_mark.fixed b/tests/ui/needless_question_mark.fixed index 7eaca571992f..679b73d404a6 100644 --- a/tests/ui/needless_question_mark.fixed +++ b/tests/ui/needless_question_mark.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_question_mark)] #![allow( diff --git a/tests/ui/needless_question_mark.rs b/tests/ui/needless_question_mark.rs index 960bc7b78983..a993d3ec35d8 100644 --- a/tests/ui/needless_question_mark.rs +++ b/tests/ui/needless_question_mark.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_question_mark)] #![allow( diff --git a/tests/ui/needless_range_loop.rs b/tests/ui/needless_range_loop.rs index 921801138a9b..033827675154 100644 --- a/tests/ui/needless_range_loop.rs +++ b/tests/ui/needless_range_loop.rs @@ -1,5 +1,19 @@ #![warn(clippy::needless_range_loop)] -#![allow(clippy::uninlined_format_args)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> bfd5abad4 (Fix all the other tests) +#![allow( + clippy::uninlined_format_args, + clippy::unnecessary_literal_unwrap, + clippy::useless_vec +)] +<<<<<<< HEAD +======= +#![allow(clippy::uninlined_format_args, clippy::useless_vec)] +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +>>>>>>> bfd5abad4 (Fix all the other tests) static STATIC: [usize; 4] = [0, 1, 8, 16]; const CONST: [usize; 4] = [0, 1, 8, 16]; @@ -82,6 +96,29 @@ fn main() { for i in 0..2 { println!("{}", test[i]); } + + // See #601 + for i in 0..10 { + // no error, id_col does not exist outside the loop + let mut id_col = [0f64; 10]; + id_col[i] = 1f64; + } + + fn f(_: &T, _: &T) -> bool { + unimplemented!() + } + fn g(_: &mut [T], _: usize, _: usize) { + unimplemented!() + } + for i in 1..vec.len() { + if f(&vec[i - 1], &vec[i]) { + g(&mut vec, i - 1, i); + } + } + + for mid in 1..vec.len() { + let (_, _) = vec.split_at(mid); + } } struct Test { @@ -94,3 +131,38 @@ impl std::ops::Index for Test { &self.inner[index] } } + +fn partition(v: &mut [T]) -> usize { + let pivot = v.len() - 1; + let mut i = 0; + for j in 0..pivot { + if v[j] <= v[pivot] { + v.swap(i, j); + i += 1; + } + } + v.swap(i, pivot); + i +} + +pub fn manual_copy_same_destination(dst: &mut [i32], d: usize, s: usize) { + // Same source and destination - don't trigger lint + for i in 0..dst.len() { + dst[d + i] = dst[s + i]; + } +} + +mod issue_2496 { + pub trait Handle { + fn new_for_index(index: usize) -> Self; + fn index(&self) -> usize; + } + + pub fn test() -> H { + for x in 0..5 { + let next_handle = H::new_for_index(x); + println!("{}", next_handle.index()); + } + unimplemented!() + } +} diff --git a/tests/ui/needless_range_loop.stderr b/tests/ui/needless_range_loop.stderr index cffa19bec3a6..8ca6b880ceae 100644 --- a/tests/ui/needless_range_loop.stderr +++ b/tests/ui/needless_range_loop.stderr @@ -1,5 +1,5 @@ error: the loop variable `i` is only used to index `vec` - --> $DIR/needless_range_loop.rs:11:14 + --> $DIR/needless_range_loop.rs:15:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL | for in &vec { | ~~~~~~ ~~~~ error: the loop variable `i` is only used to index `vec` - --> $DIR/needless_range_loop.rs:20:14 + --> $DIR/needless_range_loop.rs:24:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | for in &vec { | ~~~~~~ ~~~~ error: the loop variable `j` is only used to index `STATIC` - --> $DIR/needless_range_loop.rs:25:14 + --> $DIR/needless_range_loop.rs:29:14 | LL | for j in 0..4 { | ^^^^ @@ -33,7 +33,7 @@ LL | for in &STATIC { | ~~~~~~ ~~~~~~~ error: the loop variable `j` is only used to index `CONST` - --> $DIR/needless_range_loop.rs:29:14 + --> $DIR/needless_range_loop.rs:33:14 | LL | for j in 0..4 { | ^^^^ @@ -44,7 +44,7 @@ LL | for in &CONST { | ~~~~~~ ~~~~~~ error: the loop variable `i` is used to index `vec` - --> $DIR/needless_range_loop.rs:33:14 + --> $DIR/needless_range_loop.rs:37:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | for (i, ) in vec.iter().enumerate() { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec2` - --> $DIR/needless_range_loop.rs:41:14 + --> $DIR/needless_range_loop.rs:45:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | for in vec2.iter().take(vec.len()) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> $DIR/needless_range_loop.rs:45:14 + --> $DIR/needless_range_loop.rs:49:14 | LL | for i in 5..vec.len() { | ^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | for in vec.iter().skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> $DIR/needless_range_loop.rs:49:14 + --> $DIR/needless_range_loop.rs:53:14 | LL | for i in 0..MAX_LEN { | ^^^^^^^^^^ @@ -88,7 +88,7 @@ LL | for in vec.iter().take(MAX_LEN) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> $DIR/needless_range_loop.rs:53:14 + --> $DIR/needless_range_loop.rs:57:14 | LL | for i in 0..=MAX_LEN { | ^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL | for in vec.iter().take(MAX_LEN + 1) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> $DIR/needless_range_loop.rs:57:14 + --> $DIR/needless_range_loop.rs:61:14 | LL | for i in 5..10 { | ^^^^^ @@ -110,7 +110,7 @@ LL | for in vec.iter().take(10).skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> $DIR/needless_range_loop.rs:61:14 + --> $DIR/needless_range_loop.rs:65:14 | LL | for i in 5..=10 { | ^^^^^^ @@ -121,7 +121,7 @@ LL | for in vec.iter().take(10 + 1).skip(5) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> $DIR/needless_range_loop.rs:65:14 + --> $DIR/needless_range_loop.rs:69:14 | LL | for i in 5..vec.len() { | ^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL | for (i, ) in vec.iter().enumerate().skip(5) { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> $DIR/needless_range_loop.rs:69:14 + --> $DIR/needless_range_loop.rs:73:14 | LL | for i in 5..10 { | ^^^^^ @@ -143,7 +143,7 @@ LL | for (i, ) in vec.iter().enumerate().take(10).skip(5) { | ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is used to index `vec` - --> $DIR/needless_range_loop.rs:74:14 + --> $DIR/needless_range_loop.rs:78:14 | LL | for i in 0..vec.len() { | ^^^^^^^^^^^^ diff --git a/tests/ui/needless_range_loop2.rs b/tests/ui/needless_range_loop2.rs index 7633316e0f87..516d99a3532a 100644 --- a/tests/ui/needless_range_loop2.rs +++ b/tests/ui/needless_range_loop2.rs @@ -1,4 +1,5 @@ #![warn(clippy::needless_range_loop)] +#![allow(clippy::useless_vec)] fn calc_idx(i: usize) -> usize { (i + i + 20) % 4 diff --git a/tests/ui/needless_range_loop2.stderr b/tests/ui/needless_range_loop2.stderr index 1e6ec5e667aa..8c4f5d954a97 100644 --- a/tests/ui/needless_range_loop2.stderr +++ b/tests/ui/needless_range_loop2.stderr @@ -1,5 +1,5 @@ error: the loop variable `i` is only used to index `ns` - --> $DIR/needless_range_loop2.rs:10:14 + --> $DIR/needless_range_loop2.rs:11:14 | LL | for i in 3..10 { | ^^^^^ @@ -11,7 +11,7 @@ LL | for in ns.iter().take(10).skip(3) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `ms` - --> $DIR/needless_range_loop2.rs:31:14 + --> $DIR/needless_range_loop2.rs:32:14 | LL | for i in 0..ms.len() { | ^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | for in &mut ms { | ~~~~~~ ~~~~~~~ error: the loop variable `i` is only used to index `ms` - --> $DIR/needless_range_loop2.rs:37:14 + --> $DIR/needless_range_loop2.rs:38:14 | LL | for i in 0..ms.len() { | ^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | for in &mut ms { | ~~~~~~ ~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> $DIR/needless_range_loop2.rs:61:14 + --> $DIR/needless_range_loop2.rs:62:14 | LL | for i in x..x + 4 { | ^^^^^^^^ @@ -44,7 +44,7 @@ LL | for in vec.iter_mut().skip(x).take(4) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `vec` - --> $DIR/needless_range_loop2.rs:68:14 + --> $DIR/needless_range_loop2.rs:69:14 | LL | for i in x..=x + 4 { | ^^^^^^^^^ @@ -55,7 +55,7 @@ LL | for in vec.iter_mut().skip(x).take(4 + 1) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `arr` - --> $DIR/needless_range_loop2.rs:74:14 + --> $DIR/needless_range_loop2.rs:75:14 | LL | for i in 0..3 { | ^^^^ @@ -66,7 +66,7 @@ LL | for in &arr { | ~~~~~~ ~~~~ error: the loop variable `i` is only used to index `arr` - --> $DIR/needless_range_loop2.rs:78:14 + --> $DIR/needless_range_loop2.rs:79:14 | LL | for i in 0..2 { | ^^^^ @@ -77,7 +77,7 @@ LL | for in arr.iter().take(2) { | ~~~~~~ ~~~~~~~~~~~~~~~~~~ error: the loop variable `i` is only used to index `arr` - --> $DIR/needless_range_loop2.rs:82:14 + --> $DIR/needless_range_loop2.rs:83:14 | LL | for i in 1..3 { | ^^^^ diff --git a/tests/ui/needless_raw_string.fixed b/tests/ui/needless_raw_string.fixed new file mode 100644 index 000000000000..5ed2bcc51d37 --- /dev/null +++ b/tests/ui/needless_raw_string.fixed @@ -0,0 +1,31 @@ +//@run-rustfix +#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)] +<<<<<<< HEAD +<<<<<<< HEAD +#![warn(clippy::needless_raw_strings)] +======= +#![warn(clippy::needless_raw_string)] +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= +#![warn(clippy::needless_raw_strings)] +>>>>>>> 8cb6c8699 (change category and refactor) +#![feature(c_str_literals)] + +fn main() { + "aaa"; + r#""aaa""#; + r#"\s"#; + b"aaa"; + br#""aaa""#; + br#"\s"#; +<<<<<<< HEAD + // currently disabled: https://github.com/rust-lang/rust/issues/113333 + // cr#"aaa"#; + // cr#""aaa""#; + // cr#"\s"#; +======= + c"aaa"; + cr#""aaa""#; + cr#"\s"#; +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +} diff --git a/tests/ui/needless_raw_string.rs b/tests/ui/needless_raw_string.rs new file mode 100644 index 000000000000..d6dc9b1f1f9f --- /dev/null +++ b/tests/ui/needless_raw_string.rs @@ -0,0 +1,31 @@ +//@run-rustfix +#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)] +<<<<<<< HEAD +<<<<<<< HEAD +#![warn(clippy::needless_raw_strings)] +======= +#![warn(clippy::needless_raw_string)] +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= +#![warn(clippy::needless_raw_strings)] +>>>>>>> 8cb6c8699 (change category and refactor) +#![feature(c_str_literals)] + +fn main() { + r#"aaa"#; + r#""aaa""#; + r#"\s"#; + br#"aaa"#; + br#""aaa""#; + br#"\s"#; +<<<<<<< HEAD + // currently disabled: https://github.com/rust-lang/rust/issues/113333 + // cr#"aaa"#; + // cr#""aaa""#; + // cr#"\s"#; +======= + cr#"aaa"#; + cr#""aaa""#; + cr#"\s"#; +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +} diff --git a/tests/ui/needless_raw_string.stderr b/tests/ui/needless_raw_string.stderr new file mode 100644 index 000000000000..6e093ddb462a --- /dev/null +++ b/tests/ui/needless_raw_string.stderr @@ -0,0 +1,34 @@ +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:7:5 + | +LL | r#"aaa"#; + | ^^^^^^^^ help: try: `"aaa"` + | +<<<<<<< HEAD +<<<<<<< HEAD + = note: `-D clippy::needless-raw-strings` implied by `-D warnings` +======= + = note: `-D clippy::needless-raw-string` implied by `-D warnings` +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= + = note: `-D clippy::needless-raw-strings` implied by `-D warnings` +>>>>>>> 8cb6c8699 (change category and refactor) + +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:10:5 + | +LL | br#"aaa"#; + | ^^^^^^^^^ help: try: `b"aaa"` + +<<<<<<< HEAD +error: aborting due to 2 previous errors +======= +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:13:5 + | +LL | cr#"aaa"#; + | ^^^^^^^^^ help: try: `c"aaa"` + +error: aborting due to 3 previous errors +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) + diff --git a/tests/ui/needless_raw_string_hashes.fixed b/tests/ui/needless_raw_string_hashes.fixed new file mode 100644 index 000000000000..5f1dc47a3a17 --- /dev/null +++ b/tests/ui/needless_raw_string_hashes.fixed @@ -0,0 +1,46 @@ +//@run-rustfix +#![allow(clippy::no_effect, unused)] +#![warn(clippy::needless_raw_string_hashes)] +#![feature(c_str_literals)] + +fn main() { +<<<<<<< HEAD +<<<<<<< HEAD + r#"aaa"#; + r#"Hello "world"!"#; + r####" "### "## "# "####; + r###" "aa" "# "## "###; + br#"aaa"#; + br#"Hello "world"!"#; + br####" "### "## "# "####; + br###" "aa" "# "## "###; + // currently disabled: https://github.com/rust-lang/rust/issues/113333 + // cr#"aaa"#; + // cr##"Hello "world"!"##; + // cr######" "### "## "# "######; + // cr######" "aa" "# "## "######; +======= + r"aaa"; +======= + r#"aaa"#; +>>>>>>> cb52d19ce (don't lint `needless_raw_string_hashes` when it's unnecessary) + r#"Hello "world"!"#; + r####" "### "## "# "####; + r###" "aa" "# "## "###; + br#"aaa"#; + br#"Hello "world"!"#; + br####" "### "## "# "####; + br###" "aa" "# "## "###; + cr#"aaa"#; + cr#"Hello "world"!"#; + cr####" "### "## "# "####; + cr###" "aa" "# "## "###; +<<<<<<< HEAD +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= + // Issue #11068, do not lint + r##"a"#"a"##; + br##"a"#"a"##; + cr##"a"#"a"##; +>>>>>>> 9a581077d (Fix FP [`needless_raw_string_hashes`]) +} diff --git a/tests/ui/needless_raw_string_hashes.rs b/tests/ui/needless_raw_string_hashes.rs new file mode 100644 index 000000000000..0a118022ddaa --- /dev/null +++ b/tests/ui/needless_raw_string_hashes.rs @@ -0,0 +1,34 @@ +//@run-rustfix +#![allow(clippy::no_effect, unused)] +#![warn(clippy::needless_raw_string_hashes)] +#![feature(c_str_literals)] + +fn main() { + r#"aaa"#; + r##"Hello "world"!"##; + r######" "### "## "# "######; + r######" "aa" "# "## "######; + br#"aaa"#; + br##"Hello "world"!"##; + br######" "### "## "# "######; + br######" "aa" "# "## "######; +<<<<<<< HEAD + // currently disabled: https://github.com/rust-lang/rust/issues/113333 + // cr#"aaa"#; + // cr##"Hello "world"!"##; + // cr######" "### "## "# "######; + // cr######" "aa" "# "## "######; +======= + cr#"aaa"#; + cr##"Hello "world"!"##; + cr######" "### "## "# "######; + cr######" "aa" "# "## "######; +<<<<<<< HEAD +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= + // Issue #11068, do not lint + r##"a"#"a"##; + br##"a"#"a"##; + cr##"a"#"a"##; +>>>>>>> 9a581077d (Fix FP [`needless_raw_string_hashes`]) +} diff --git a/tests/ui/needless_raw_string_hashes.stderr b/tests/ui/needless_raw_string_hashes.stderr new file mode 100644 index 000000000000..166fbe7d1a86 --- /dev/null +++ b/tests/ui/needless_raw_string_hashes.stderr @@ -0,0 +1,100 @@ +error: unnecessary hashes around raw string literal +<<<<<<< HEAD +<<<<<<< HEAD +======= + --> $DIR/needless_raw_string_hashes.rs:7:5 + | +LL | r#"aaa"#; + | ^^^^^^^^ help: try: `r"aaa"` + | + = note: `-D clippy::needless-raw-string-hashes` implied by `-D warnings` + +error: unnecessary hashes around raw string literal +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= +>>>>>>> cb52d19ce (don't lint `needless_raw_string_hashes` when it's unnecessary) + --> $DIR/needless_raw_string_hashes.rs:8:5 + | +LL | r##"Hello "world"!"##; + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `r#"Hello "world"!"#` +<<<<<<< HEAD +<<<<<<< HEAD + | + = note: `-D clippy::needless-raw-string-hashes` implied by `-D warnings` +======= +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= + | + = note: `-D clippy::needless-raw-string-hashes` implied by `-D warnings` +>>>>>>> cb52d19ce (don't lint `needless_raw_string_hashes` when it's unnecessary) + +error: unnecessary hashes around raw string literal + --> $DIR/needless_raw_string_hashes.rs:9:5 + | +LL | r######" "### "## "# "######; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `r####" "### "## "# "####` + +error: unnecessary hashes around raw string literal + --> $DIR/needless_raw_string_hashes.rs:10:5 + | +LL | r######" "aa" "# "## "######; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `r###" "aa" "# "## "###` + +error: unnecessary hashes around raw string literal +<<<<<<< HEAD +<<<<<<< HEAD +======= + --> $DIR/needless_raw_string_hashes.rs:11:5 + | +LL | br#"aaa"#; + | ^^^^^^^^^ help: try: `br"aaa"` + +error: unnecessary hashes around raw string literal +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= +>>>>>>> cb52d19ce (don't lint `needless_raw_string_hashes` when it's unnecessary) + --> $DIR/needless_raw_string_hashes.rs:12:5 + | +LL | br##"Hello "world"!"##; + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `br#"Hello "world"!"#` + +error: unnecessary hashes around raw string literal + --> $DIR/needless_raw_string_hashes.rs:13:5 + | +LL | br######" "### "## "# "######; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `br####" "### "## "# "####` + +error: unnecessary hashes around raw string literal + --> $DIR/needless_raw_string_hashes.rs:14:5 + | +LL | br######" "aa" "# "## "######; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `br###" "aa" "# "## "###` + +<<<<<<< HEAD +error: aborting due to 6 previous errors +======= +error: unnecessary hashes around raw string literal + --> $DIR/needless_raw_string_hashes.rs:16:5 + | +LL | cr##"Hello "world"!"##; + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cr#"Hello "world"!"#` + +error: unnecessary hashes around raw string literal + --> $DIR/needless_raw_string_hashes.rs:17:5 + | +LL | cr######" "### "## "# "######; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cr####" "### "## "# "####` + +error: unnecessary hashes around raw string literal + --> $DIR/needless_raw_string_hashes.rs:18:5 + | +LL | cr######" "aa" "# "## "######; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cr###" "aa" "# "## "###` + +<<<<<<< HEAD +error: aborting due to 12 previous errors +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= +error: aborting due to 9 previous errors +>>>>>>> cb52d19ce (don't lint `needless_raw_string_hashes` when it's unnecessary) + diff --git a/tests/ui/needless_return.fixed b/tests/ui/needless_return.fixed index 57c08996ce25..4dabf313963d 100644 --- a/tests/ui/needless_return.fixed +++ b/tests/ui/needless_return.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![feature(yeet_expr)] @@ -7,7 +7,8 @@ clippy::if_same_then_else, clippy::single_match, clippy::needless_bool, - clippy::equatable_if_let + clippy::equatable_if_let, + clippy::needless_else )] #![warn(clippy::needless_return)] @@ -231,8 +232,9 @@ fn needless_return_macro() -> String { } fn issue_9361() -> i32 { - #[allow(clippy::integer_arithmetic)] - return 1 + 2; + let n = 1; + #[allow(clippy::arithmetic_side_effects)] + return n + n; } fn issue8336(x: i32) -> bool { diff --git a/tests/ui/needless_return.rs b/tests/ui/needless_return.rs index 7c1feefbe32b..542f562b3149 100644 --- a/tests/ui/needless_return.rs +++ b/tests/ui/needless_return.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![feature(yeet_expr)] @@ -7,7 +7,8 @@ clippy::if_same_then_else, clippy::single_match, clippy::needless_bool, - clippy::equatable_if_let + clippy::equatable_if_let, + clippy::needless_else )] #![warn(clippy::needless_return)] @@ -239,8 +240,9 @@ fn needless_return_macro() -> String { } fn issue_9361() -> i32 { - #[allow(clippy::integer_arithmetic)] - return 1 + 2; + let n = 1; + #[allow(clippy::arithmetic_side_effects)] + return n + n; } fn issue8336(x: i32) -> bool { diff --git a/tests/ui/needless_return.stderr b/tests/ui/needless_return.stderr index 87d0cd3e14cf..a2012b01762e 100644 --- a/tests/ui/needless_return.stderr +++ b/tests/ui/needless_return.stderr @@ -1,390 +1,652 @@ error: unneeded `return` statement - --> $DIR/needless_return.rs:27:5 + --> $DIR/needless_return.rs:28:5 | LL | return true; | ^^^^^^^^^^^ | = note: `-D clippy::needless-return` implied by `-D warnings` - = help: remove `return` +help: remove `return` + | +LL - return true; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:31:5 + --> $DIR/needless_return.rs:32:5 | LL | return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return true; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:36:5 + --> $DIR/needless_return.rs:37:5 | LL | return true;;; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return true;;; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:41:5 + --> $DIR/needless_return.rs:42:5 | LL | return true;; ; ; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return true;; ; ; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:46:9 + --> $DIR/needless_return.rs:47:9 | LL | return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return true; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:48:9 + --> $DIR/needless_return.rs:49:9 | LL | return false; | ^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return false; +LL + false + | error: unneeded `return` statement - --> $DIR/needless_return.rs:54:17 + --> $DIR/needless_return.rs:55:17 | LL | true => return false, | ^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL | true => false, + | ~~~~~ error: unneeded `return` statement - --> $DIR/needless_return.rs:56:13 + --> $DIR/needless_return.rs:57:13 | LL | return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return true; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:63:9 + --> $DIR/needless_return.rs:64:9 | LL | return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return true; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:65:16 + --> $DIR/needless_return.rs:66:16 | LL | let _ = || return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL | let _ = || true; + | ~~~~ error: unneeded `return` statement - --> $DIR/needless_return.rs:69:5 + --> $DIR/needless_return.rs:70:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return the_answer!(); +LL + the_answer!() + | error: unneeded `return` statement - --> $DIR/needless_return.rs:72:21 + --> $DIR/needless_return.rs:73:21 | LL | fn test_void_fun() { | _____________________^ LL | | return; | |__________^ | - = help: remove `return` +help: remove `return` + | +LL - fn test_void_fun() { +LL - return; +LL + fn test_void_fun() { + | error: unneeded `return` statement - --> $DIR/needless_return.rs:77:11 + --> $DIR/needless_return.rs:78:11 | LL | if b { | ___________^ LL | | return; | |______________^ | - = help: remove `return` +help: remove `return` + | +LL - if b { +LL - return; +LL + if b { + | error: unneeded `return` statement - --> $DIR/needless_return.rs:79:13 + --> $DIR/needless_return.rs:80:13 | LL | } else { | _____________^ LL | | return; | |______________^ | - = help: remove `return` +help: remove `return` + | +LL - } else { +LL - return; +LL + } else { + | error: unneeded `return` statement - --> $DIR/needless_return.rs:87:14 + --> $DIR/needless_return.rs:88:14 | LL | _ => return, | ^^^^^^ | - = help: replace `return` with a unit value +help: replace `return` with a unit value + | +LL | _ => (), + | ~~ error: unneeded `return` statement - --> $DIR/needless_return.rs:95:24 + --> $DIR/needless_return.rs:96:24 | LL | let _ = 42; | ________________________^ LL | | return; | |__________________^ | - = help: remove `return` +help: remove `return` + | +LL - let _ = 42; +LL - return; +LL + let _ = 42; + | error: unneeded `return` statement - --> $DIR/needless_return.rs:98:14 + --> $DIR/needless_return.rs:99:14 | LL | _ => return, | ^^^^^^ | - = help: replace `return` with a unit value +help: replace `return` with a unit value + | +LL | _ => (), + | ~~ error: unneeded `return` statement - --> $DIR/needless_return.rs:111:9 + --> $DIR/needless_return.rs:112:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return String::from("test"); +LL + String::from("test") + | error: unneeded `return` statement - --> $DIR/needless_return.rs:113:9 + --> $DIR/needless_return.rs:114:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return String::new(); +LL + String::new() + | error: unneeded `return` statement - --> $DIR/needless_return.rs:135:32 + --> $DIR/needless_return.rs:136:32 | LL | bar.unwrap_or_else(|_| return) | ^^^^^^ | - = help: replace `return` with an empty block +help: replace `return` with an empty block + | +LL | bar.unwrap_or_else(|_| {}) + | ~~ error: unneeded `return` statement - --> $DIR/needless_return.rs:139:21 + --> $DIR/needless_return.rs:140:21 | LL | let _ = || { | _____________________^ LL | | return; | |__________________^ | - = help: remove `return` +help: remove `return` + | +LL - let _ = || { +LL - return; +LL + let _ = || { + | error: unneeded `return` statement - --> $DIR/needless_return.rs:142:20 + --> $DIR/needless_return.rs:143:20 | LL | let _ = || return; | ^^^^^^ | - = help: replace `return` with an empty block +help: replace `return` with an empty block + | +LL | let _ = || {}; + | ~~ error: unneeded `return` statement - --> $DIR/needless_return.rs:148:32 + --> $DIR/needless_return.rs:149:32 | LL | res.unwrap_or_else(|_| return Foo) | ^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL | res.unwrap_or_else(|_| Foo) + | ~~~ error: unneeded `return` statement - --> $DIR/needless_return.rs:157:5 + --> $DIR/needless_return.rs:158:5 | LL | return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return true; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:161:5 + --> $DIR/needless_return.rs:162:5 | LL | return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return true; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:166:9 + --> $DIR/needless_return.rs:167:9 | LL | return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return true; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:168:9 + --> $DIR/needless_return.rs:169:9 | LL | return false; | ^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return false; +LL + false + | error: unneeded `return` statement - --> $DIR/needless_return.rs:174:17 + --> $DIR/needless_return.rs:175:17 | LL | true => return false, | ^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL | true => false, + | ~~~~~ error: unneeded `return` statement - --> $DIR/needless_return.rs:176:13 + --> $DIR/needless_return.rs:177:13 | LL | return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return true; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:183:9 + --> $DIR/needless_return.rs:184:9 | LL | return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return true; +LL + true + | error: unneeded `return` statement - --> $DIR/needless_return.rs:185:16 + --> $DIR/needless_return.rs:186:16 | LL | let _ = || return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL | let _ = || true; + | ~~~~ error: unneeded `return` statement - --> $DIR/needless_return.rs:189:5 + --> $DIR/needless_return.rs:190:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return the_answer!(); +LL + the_answer!() + | error: unneeded `return` statement - --> $DIR/needless_return.rs:192:33 + --> $DIR/needless_return.rs:193:33 | LL | async fn async_test_void_fun() { | _________________________________^ LL | | return; | |__________^ | - = help: remove `return` +help: remove `return` + | +LL - async fn async_test_void_fun() { +LL - return; +LL + async fn async_test_void_fun() { + | error: unneeded `return` statement - --> $DIR/needless_return.rs:197:11 + --> $DIR/needless_return.rs:198:11 | LL | if b { | ___________^ LL | | return; | |______________^ | - = help: remove `return` +help: remove `return` + | +LL - if b { +LL - return; +LL + if b { + | error: unneeded `return` statement - --> $DIR/needless_return.rs:199:13 + --> $DIR/needless_return.rs:200:13 | LL | } else { | _____________^ LL | | return; | |______________^ | - = help: remove `return` +help: remove `return` + | +LL - } else { +LL - return; +LL + } else { + | error: unneeded `return` statement - --> $DIR/needless_return.rs:207:14 + --> $DIR/needless_return.rs:208:14 | LL | _ => return, | ^^^^^^ | - = help: replace `return` with a unit value +help: replace `return` with a unit value + | +LL | _ => (), + | ~~ error: unneeded `return` statement - --> $DIR/needless_return.rs:220:9 + --> $DIR/needless_return.rs:221:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return String::from("test"); +LL + String::from("test") + | error: unneeded `return` statement - --> $DIR/needless_return.rs:222:9 + --> $DIR/needless_return.rs:223:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return String::new(); +LL + String::new() + | error: unneeded `return` statement - --> $DIR/needless_return.rs:238:5 + --> $DIR/needless_return.rs:239:5 | LL | return format!("Hello {}", "world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | +<<<<<<< HEAD +<<<<<<< HEAD +help: remove `return` +======= = help: remove `return` +======= +help: remove `return` + | +LL - return format!("Hello {}", "world!"); +LL + format!("Hello {}", "world!") + | +>>>>>>> 47a024e81 (Display the `needless_return` suggestion) + +error: unneeded `return` statement +<<<<<<< HEAD + --> $DIR/needless_return.rs:250:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/needless_return.rs:251:9 +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) + | +LL - return format!("Hello {}", "world!"); +LL + format!("Hello {}", "world!") + | error: unneeded `return` statement - --> $DIR/needless_return.rs:249:9 + --> $DIR/needless_return.rs:253:9 | LL | return true; | ^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL ~ true +LL | } else { +LL | return false; +LL ~ } + | error: unneeded `return` statement - --> $DIR/needless_return.rs:251:9 + --> $DIR/needless_return.rs:253:9 | LL | return false; | ^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL ~ false +LL ~ } + | error: unneeded `return` statement - --> $DIR/needless_return.rs:258:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/needless_return.rs:260:13 +======= + --> $DIR/needless_return.rs:259:13 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/needless_return.rs:260:13 +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) | LL | return 10; | ^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL ~ 10 +LL | }, + ... +LL | }, +LL ~ } + | error: unneeded `return` statement - --> $DIR/needless_return.rs:261:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/needless_return.rs:263:13 +======= + --> $DIR/needless_return.rs:262:13 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/needless_return.rs:263:13 +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) | LL | return 100; | ^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL ~ 100 +LL | }, +LL ~ } + | error: unneeded `return` statement - --> $DIR/needless_return.rs:269:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/needless_return.rs:271:9 +======= + --> $DIR/needless_return.rs:270:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/needless_return.rs:271:9 +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) | LL | return 0; | ^^^^^^^^ | +<<<<<<< HEAD +<<<<<<< HEAD +help: remove `return` +======= = help: remove `return` +======= +help: remove `return` + | +LL ~ 0 +LL ~ } + | +>>>>>>> 47a024e81 (Display the `needless_return` suggestion) + +error: unneeded `return` statement +<<<<<<< HEAD + --> $DIR/needless_return.rs:277:13 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/needless_return.rs:278:13 +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) + | +LL ~ 0 +LL ~ } + | error: unneeded `return` statement - --> $DIR/needless_return.rs:276:13 + --> $DIR/needless_return.rs:280:13 | LL | return *(x as *const isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL ~ *(x as *const isize) +LL | } else { +LL | return !*(x as *const isize); +LL ~ } +LL ~ } + | error: unneeded `return` statement - --> $DIR/needless_return.rs:278:13 + --> $DIR/needless_return.rs:280:13 | LL | return !*(x as *const isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL ~ !*(x as *const isize) +LL ~ } +LL ~ } + | error: unneeded `return` statement - --> $DIR/needless_return.rs:285:20 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/needless_return.rs:287:20 +======= + --> $DIR/needless_return.rs:286:20 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/needless_return.rs:287:20 +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) | LL | let _ = 42; | ____________________^ @@ -392,47 +654,116 @@ LL | | LL | | return; | |______________^ | - = help: remove `return` +help: remove `return` + | +LL - let _ = 42; +LL - +LL - return; +LL + let _ = 42; + | error: unneeded `return` statement - --> $DIR/needless_return.rs:292:20 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/needless_return.rs:294:20 +======= + --> $DIR/needless_return.rs:293:20 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/needless_return.rs:294:20 +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) | LL | let _ = 42; return; | ^^^^^^^ | +<<<<<<< HEAD +<<<<<<< HEAD +help: remove `return` +======= = help: remove `return` +======= +help: remove `return` + | +LL - let _ = 42; return; +LL + let _ = 42; + | +>>>>>>> 47a024e81 (Display the `needless_return` suggestion) + +error: unneeded `return` statement +<<<<<<< HEAD + --> $DIR/needless_return.rs:305:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/needless_return.rs:306:9 +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) + | +LL - let _ = 42; return; +LL + let _ = 42; + | error: unneeded `return` statement - --> $DIR/needless_return.rs:304:9 + --> $DIR/needless_return.rs:308:9 | LL | return Ok(format!("ok!")); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return Ok(format!("ok!")); +LL + Ok(format!("ok!")) + | error: unneeded `return` statement - --> $DIR/needless_return.rs:306:9 + --> $DIR/needless_return.rs:308:9 | LL | return Err(format!("err!")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return Err(format!("err!")); +LL + Err(format!("err!")) + | error: unneeded `return` statement - --> $DIR/needless_return.rs:312:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/needless_return.rs:314:9 +======= + --> $DIR/needless_return.rs:313:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/needless_return.rs:314:9 +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) | LL | return if true { 1 } else { 2 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` +help: remove `return` + | +LL - return if true { 1 } else { 2 }; +LL + if true { 1 } else { 2 } + | error: unneeded `return` statement - --> $DIR/needless_return.rs:316:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/needless_return.rs:318:9 +======= + --> $DIR/needless_return.rs:317:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/needless_return.rs:318:9 +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) | LL | return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: remove `return` and wrap the sequence with parentheses +help: remove `return` and wrap the sequence with parentheses + | +LL - return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 }; +LL + (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 }) + | error: aborting due to 52 previous errors diff --git a/tests/ui/needless_splitn.fixed b/tests/ui/needless_splitn.fixed index 5496031fefab..30a038312c87 100644 --- a/tests/ui/needless_splitn.fixed +++ b/tests/ui/needless_splitn.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// edition:2018 +//@run-rustfix +//@edition:2018 #![warn(clippy::needless_splitn)] #![allow(clippy::iter_skip_next, clippy::iter_nth_zero, clippy::manual_split_once)] diff --git a/tests/ui/needless_splitn.rs b/tests/ui/needless_splitn.rs index 35c2465bae13..1b0b9a5981a1 100644 --- a/tests/ui/needless_splitn.rs +++ b/tests/ui/needless_splitn.rs @@ -1,5 +1,5 @@ -// run-rustfix -// edition:2018 +//@run-rustfix +//@edition:2018 #![warn(clippy::needless_splitn)] #![allow(clippy::iter_skip_next, clippy::iter_nth_zero, clippy::manual_split_once)] diff --git a/tests/ui/needless_splitn.stderr b/tests/ui/needless_splitn.stderr index f607d8e1ab5f..0005f758104a 100644 --- a/tests/ui/needless_splitn.stderr +++ b/tests/ui/needless_splitn.stderr @@ -2,7 +2,7 @@ error: unnecessary use of `splitn` --> $DIR/needless_splitn.rs:14:13 | LL | let _ = str.splitn(2, '=').next(); - | ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')` + | ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')` | = note: `-D clippy::needless-splitn` implied by `-D warnings` @@ -10,73 +10,73 @@ error: unnecessary use of `splitn` --> $DIR/needless_splitn.rs:15:13 | LL | let _ = str.splitn(2, '=').nth(0); - | ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')` + | ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')` error: unnecessary use of `splitn` --> $DIR/needless_splitn.rs:18:18 | LL | let (_, _) = str.splitn(3, '=').next_tuple().unwrap(); - | ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')` + | ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')` error: unnecessary use of `rsplitn` --> $DIR/needless_splitn.rs:21:13 | LL | let _ = str.rsplitn(2, '=').next(); - | ^^^^^^^^^^^^^^^^^^^ help: try this: `str.rsplit('=')` + | ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')` error: unnecessary use of `rsplitn` --> $DIR/needless_splitn.rs:22:13 | LL | let _ = str.rsplitn(2, '=').nth(0); - | ^^^^^^^^^^^^^^^^^^^ help: try this: `str.rsplit('=')` + | ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')` error: unnecessary use of `rsplitn` --> $DIR/needless_splitn.rs:25:18 | LL | let (_, _) = str.rsplitn(3, '=').next_tuple().unwrap(); - | ^^^^^^^^^^^^^^^^^^^ help: try this: `str.rsplit('=')` + | ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')` error: unnecessary use of `splitn` --> $DIR/needless_splitn.rs:27:13 | LL | let _ = str.splitn(5, '=').next(); - | ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')` + | ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')` error: unnecessary use of `splitn` --> $DIR/needless_splitn.rs:28:13 | LL | let _ = str.splitn(5, '=').nth(3); - | ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')` + | ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')` error: unnecessary use of `splitn` --> $DIR/needless_splitn.rs:34:13 | LL | let _ = s.splitn(2, '=').next()?; - | ^^^^^^^^^^^^^^^^ help: try this: `s.split('=')` + | ^^^^^^^^^^^^^^^^ help: try: `s.split('=')` error: unnecessary use of `splitn` --> $DIR/needless_splitn.rs:35:13 | LL | let _ = s.splitn(2, '=').nth(0)?; - | ^^^^^^^^^^^^^^^^ help: try this: `s.split('=')` + | ^^^^^^^^^^^^^^^^ help: try: `s.split('=')` error: unnecessary use of `rsplitn` --> $DIR/needless_splitn.rs:36:13 | LL | let _ = s.rsplitn(2, '=').next()?; - | ^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit('=')` + | ^^^^^^^^^^^^^^^^^ help: try: `s.rsplit('=')` error: unnecessary use of `rsplitn` --> $DIR/needless_splitn.rs:37:13 | LL | let _ = s.rsplitn(2, '=').nth(0)?; - | ^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit('=')` + | ^^^^^^^^^^^^^^^^^ help: try: `s.rsplit('=')` error: unnecessary use of `splitn` --> $DIR/needless_splitn.rs:45:13 | LL | let _ = "key=value".splitn(2, '=').nth(0).unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split('=')` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split('=')` error: aborting due to 13 previous errors diff --git a/tests/ui/neg_multiply.fixed b/tests/ui/neg_multiply.fixed index 58ab9e856783..e07e7c88d684 100644 --- a/tests/ui/neg_multiply.fixed +++ b/tests/ui/neg_multiply.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::neg_multiply)] #![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::precedence)] #![allow(unused)] diff --git a/tests/ui/neg_multiply.rs b/tests/ui/neg_multiply.rs index 581290dc72e4..2887af7b4218 100644 --- a/tests/ui/neg_multiply.rs +++ b/tests/ui/neg_multiply.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::neg_multiply)] #![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::precedence)] #![allow(unused)] diff --git a/tests/ui/never_loop.rs b/tests/ui/never_loop.rs index 29821ff96fc0..eb179f30e75e 100644 --- a/tests/ui/never_loop.rs +++ b/tests/ui/never_loop.rs @@ -1,4 +1,6 @@ +#![feature(inline_const)] #![allow( + clippy::eq_op, clippy::single_match, unused_assignments, unused_variables, @@ -295,6 +297,42 @@ pub fn test24() { } } +// Do not lint, we can evaluate `true` to always succeed thus can short-circuit before the `return` +pub fn test25() { + loop { + 'label: { + if const { true } { + break 'label; + } + return; + } + } +} + +pub fn test26() { + loop { + 'label: { + if 1 == 1 { + break 'label; + } + return; + } + } +} + +pub fn test27() { + loop { + 'label: { + let x = true; + // Lints because we cannot prove it's always `true` + if x { + break 'label; + } + return; + } + } +} + fn main() { test1(); test2(); diff --git a/tests/ui/never_loop.stderr b/tests/ui/never_loop.stderr index 704d448644e2..fd6472412dbb 100644 --- a/tests/ui/never_loop.stderr +++ b/tests/ui/never_loop.stderr @@ -1,5 +1,5 @@ error: this loop never actually loops - --> $DIR/never_loop.rs:10:5 + --> $DIR/never_loop.rs:12:5 | LL | / loop { LL | | // clippy::never_loop @@ -13,7 +13,7 @@ LL | | } = note: `#[deny(clippy::never_loop)]` on by default error: this loop never actually loops - --> $DIR/never_loop.rs:32:5 + --> $DIR/never_loop.rs:34:5 | LL | / loop { LL | | // never loops @@ -23,7 +23,7 @@ LL | | } | |_____^ error: this loop never actually loops - --> $DIR/never_loop.rs:52:5 + --> $DIR/never_loop.rs:54:5 | LL | / loop { LL | | // never loops @@ -35,7 +35,7 @@ LL | | } | |_____^ error: this loop never actually loops - --> $DIR/never_loop.rs:54:9 + --> $DIR/never_loop.rs:56:9 | LL | / while i == 0 { LL | | // never loops @@ -44,7 +44,7 @@ LL | | } | |_________^ error: this loop never actually loops - --> $DIR/never_loop.rs:66:9 + --> $DIR/never_loop.rs:68:9 | LL | / loop { LL | | // never loops @@ -56,7 +56,7 @@ LL | | } | |_________^ error: this loop never actually loops - --> $DIR/never_loop.rs:102:5 + --> $DIR/never_loop.rs:104:5 | LL | / while let Some(y) = x { LL | | // never loops @@ -65,7 +65,7 @@ LL | | } | |_____^ error: this loop never actually loops - --> $DIR/never_loop.rs:109:5 + --> $DIR/never_loop.rs:111:5 | LL | / for x in 0..10 { LL | | // never loops @@ -82,7 +82,7 @@ LL | if let Some(x) = (0..10).next() { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: this loop never actually loops - --> $DIR/never_loop.rs:157:5 + --> $DIR/never_loop.rs:159:5 | LL | / 'outer: while a { LL | | // never loops @@ -94,7 +94,7 @@ LL | | } | |_____^ error: this loop never actually loops - --> $DIR/never_loop.rs:172:9 + --> $DIR/never_loop.rs:174:9 | LL | / while false { LL | | break 'label; @@ -102,7 +102,7 @@ LL | | } | |_________^ error: this loop never actually loops - --> $DIR/never_loop.rs:223:13 + --> $DIR/never_loop.rs:225:13 | LL | let _ = loop { | _____________^ @@ -115,7 +115,7 @@ LL | | }; | |_____^ error: this loop never actually loops - --> $DIR/never_loop.rs:244:5 + --> $DIR/never_loop.rs:246:5 | LL | / 'a: loop { LL | | 'b: { @@ -126,8 +126,24 @@ LL | | } LL | | } | |_____^ +error: sub-expression diverges +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/never_loop.rs:249:17 +======= + --> $DIR/never_loop.rs:247:17 +>>>>>>> 5825b9e3e (actually fix it) +======= + --> $DIR/never_loop.rs:249:17 +>>>>>>> 6a1084c26 (Check if `if` conditions always evaluate to true in `never_loop`) + | +LL | break 'a; + | ^^^^^^^^ + | + = note: `-D clippy::diverging-sub-expression` implied by `-D warnings` + error: this loop never actually loops - --> $DIR/never_loop.rs:278:13 + --> $DIR/never_loop.rs:280:13 | LL | / for _ in 0..20 { LL | | break 'block; @@ -139,5 +155,27 @@ help: if you need the first element of the iterator, try writing LL | if let Some(_) = (0..20).next() { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 12 previous errors +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 6a1084c26 (Check if `if` conditions always evaluate to true in `never_loop`) +error: this loop never actually loops + --> $DIR/never_loop.rs:324:5 + | +LL | / loop { +LL | | 'label: { +LL | | let x = true; +LL | | // Lints because we cannot prove it's always `true` +... | +LL | | } +LL | | } + | |_____^ + +error: aborting due to 14 previous errors +<<<<<<< HEAD +======= +error: aborting due to 13 previous errors +>>>>>>> 5825b9e3e (actually fix it) +======= +>>>>>>> 6a1084c26 (Check if `if` conditions always evaluate to true in `never_loop`) diff --git a/tests/ui/new_ret_no_self.rs b/tests/ui/new_ret_no_self.rs index a2a30c8b931c..4eff62b85ff6 100644 --- a/tests/ui/new_ret_no_self.rs +++ b/tests/ui/new_ret_no_self.rs @@ -401,25 +401,3 @@ mod issue7344 { } } } - -mod issue10041 { - struct Bomb; - - impl Bomb { - // Hidden default generic parameter. - pub fn new() -> impl PartialOrd { - 0i32 - } - } - - // TAIT with self-referencing bounds - type X = impl std::ops::Add; - - struct Bomb2; - - impl Bomb2 { - pub fn new() -> X { - 0i32 - } - } -} diff --git a/tests/ui/new_ret_no_self.stderr b/tests/ui/new_ret_no_self.stderr index 2eaebfb5cac5..2b053b462b16 100644 --- a/tests/ui/new_ret_no_self.stderr +++ b/tests/ui/new_ret_no_self.stderr @@ -92,21 +92,5 @@ LL | | unimplemented!() LL | | } | |_________^ -error: methods called `new` usually return `Self` - --> $DIR/new_ret_no_self.rs:410:9 - | -LL | / pub fn new() -> impl PartialOrd { -LL | | 0i32 -LL | | } - | |_________^ - -error: methods called `new` usually return `Self` - --> $DIR/new_ret_no_self.rs:421:9 - | -LL | / pub fn new() -> X { -LL | | 0i32 -LL | | } - | |_________^ - -error: aborting due to 14 previous errors +error: aborting due to 12 previous errors diff --git a/tests/ui/new_ret_no_self_overflow.rs b/tests/ui/new_ret_no_self_overflow.rs new file mode 100644 index 000000000000..7bc6fec10ba6 --- /dev/null +++ b/tests/ui/new_ret_no_self_overflow.rs @@ -0,0 +1,26 @@ +#![feature(type_alias_impl_trait)] +#![warn(clippy::new_ret_no_self)] + +mod issue10041 { + struct Bomb; + + impl Bomb { + // Hidden default generic parameter. + pub fn new() -> impl PartialOrd { + 0i32 + } + } + + // TAIT with self-referencing bounds + type X = impl std::ops::Add; + + struct Bomb2; + + impl Bomb2 { + pub fn new() -> X { + 0i32 + } + } +} + +fn main() {} diff --git a/tests/ui/new_ret_no_self_overflow.stderr b/tests/ui/new_ret_no_self_overflow.stderr new file mode 100644 index 000000000000..babb634fdcd1 --- /dev/null +++ b/tests/ui/new_ret_no_self_overflow.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Output == issue10041::X` + --> $DIR/new_ret_no_self_overflow.rs:20:25 + | +LL | pub fn new() -> X { + | ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/no_effect.rs b/tests/ui/no_effect.rs index 1e42e1fbabfe..6a726941be89 100644 --- a/tests/ui/no_effect.rs +++ b/tests/ui/no_effect.rs @@ -5,7 +5,8 @@ clippy::deref_addrof, clippy::redundant_field_names, clippy::uninlined_format_args, - clippy::unnecessary_struct_initialization + clippy::unnecessary_struct_initialization, + clippy::useless_vec )] struct Unit; diff --git a/tests/ui/no_effect.stderr b/tests/ui/no_effect.stderr index f10f2bcf2a8a..64edfc32504e 100644 --- a/tests/ui/no_effect.stderr +++ b/tests/ui/no_effect.stderr @@ -1,5 +1,5 @@ error: statement with no effect - --> $DIR/no_effect.rs:97:5 + --> $DIR/no_effect.rs:98:5 | LL | 0; | ^^ @@ -7,151 +7,151 @@ LL | 0; = note: `-D clippy::no-effect` implied by `-D warnings` error: statement with no effect - --> $DIR/no_effect.rs:98:5 + --> $DIR/no_effect.rs:99:5 | LL | s2; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:99:5 + --> $DIR/no_effect.rs:100:5 | LL | Unit; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:100:5 + --> $DIR/no_effect.rs:101:5 | LL | Tuple(0); | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:101:5 + --> $DIR/no_effect.rs:102:5 | LL | Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:102:5 + --> $DIR/no_effect.rs:103:5 | LL | Struct { ..s }; | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:103:5 + --> $DIR/no_effect.rs:104:5 | LL | Union { a: 0 }; | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:104:5 + --> $DIR/no_effect.rs:105:5 | LL | Enum::Tuple(0); | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:105:5 + --> $DIR/no_effect.rs:106:5 | LL | Enum::Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:106:5 + --> $DIR/no_effect.rs:107:5 | LL | 5 + 6; | ^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:107:5 + --> $DIR/no_effect.rs:108:5 | LL | *&42; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:108:5 + --> $DIR/no_effect.rs:109:5 | LL | &6; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:109:5 + --> $DIR/no_effect.rs:110:5 | LL | (5, 6, 7); | ^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:110:5 + --> $DIR/no_effect.rs:111:5 | LL | ..; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:111:5 + --> $DIR/no_effect.rs:112:5 | LL | 5..; | ^^^^ error: statement with no effect - --> $DIR/no_effect.rs:112:5 + --> $DIR/no_effect.rs:113:5 | LL | ..5; | ^^^^ error: statement with no effect - --> $DIR/no_effect.rs:113:5 + --> $DIR/no_effect.rs:114:5 | LL | 5..6; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:114:5 + --> $DIR/no_effect.rs:115:5 | LL | 5..=6; | ^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:115:5 + --> $DIR/no_effect.rs:116:5 | LL | [42, 55]; | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:116:5 + --> $DIR/no_effect.rs:117:5 | LL | [42, 55][1]; | ^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:117:5 + --> $DIR/no_effect.rs:118:5 | LL | (42, 55).1; | ^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:118:5 + --> $DIR/no_effect.rs:119:5 | LL | [42; 55]; | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:119:5 + --> $DIR/no_effect.rs:120:5 | LL | [42; 55][13]; | ^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:121:5 + --> $DIR/no_effect.rs:122:5 | LL | || x += 5; | ^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:123:5 + --> $DIR/no_effect.rs:124:5 | LL | FooString { s: s }; | ^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:124:5 + --> $DIR/no_effect.rs:125:5 | LL | let _unused = 1; | ^^^^^^^^^^^^^^^^ @@ -159,19 +159,19 @@ LL | let _unused = 1; = note: `-D clippy::no-effect-underscore-binding` implied by `-D warnings` error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:125:5 + --> $DIR/no_effect.rs:126:5 | LL | let _penguin = || println!("Some helpful closure"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:126:5 + --> $DIR/no_effect.rs:127:5 | LL | let _duck = Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:127:5 + --> $DIR/no_effect.rs:128:5 | LL | let _cat = [2, 4, 6, 8][2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/no_effect_return.rs b/tests/ui/no_effect_return.rs new file mode 100644 index 000000000000..231dd063ad89 --- /dev/null +++ b/tests/ui/no_effect_return.rs @@ -0,0 +1,81 @@ +#![allow(clippy::unused_unit, dead_code, unused)] +#![no_main] + +use std::ops::ControlFlow; + +fn a() -> u32 { + { + 0u32; + } + 0 +} + +async fn b() -> u32 { + { + 0u32; + } + 0 +} + +type C = i32; +async fn c() -> C { + { + 0i32 as C; + } + 0 +} + +fn d() -> u128 { + { + // not last stmt + 0u128; + println!("lol"); + } + 0 +} + +fn e() -> u32 { + { + // mismatched types + 0u16; + } + 0 +} + +fn f() -> [u16; 1] { + { + [1u16]; + } + [1] +} + +fn g() -> ControlFlow<()> { + { + ControlFlow::Break::<()>(()); + } + ControlFlow::Continue(()) +} + +fn h() -> Vec { + { + // function call, so this won't trigger `no_effect`. not an issue with this change, but the + // lint itself (but also not really.) + vec![0u16]; + } + vec![] +} + +fn i() -> () { + { + (); + } + () +} + +fn j() { + { + // does not suggest on function without explicit return type + (); + } + () +} diff --git a/tests/ui/no_effect_return.stderr b/tests/ui/no_effect_return.stderr new file mode 100644 index 000000000000..779900e18590 --- /dev/null +++ b/tests/ui/no_effect_return.stderr @@ -0,0 +1,70 @@ +error: statement with no effect + --> $DIR/no_effect_return.rs:8:9 + | +LL | 0u32; + | -^^^^ + | | + | help: did you mean to return it?: `return` + | + = note: `-D clippy::no-effect` implied by `-D warnings` + +error: statement with no effect + --> $DIR/no_effect_return.rs:15:9 + | +LL | 0u32; + | -^^^^ + | | + | help: did you mean to return it?: `return` + +error: statement with no effect + --> $DIR/no_effect_return.rs:23:9 + | +LL | 0i32 as C; + | -^^^^^^^^^ + | | + | help: did you mean to return it?: `return` + +error: statement with no effect + --> $DIR/no_effect_return.rs:31:9 + | +LL | 0u128; + | ^^^^^^ + +error: statement with no effect + --> $DIR/no_effect_return.rs:40:9 + | +LL | 0u16; + | ^^^^^ + +error: statement with no effect + --> $DIR/no_effect_return.rs:47:9 + | +LL | [1u16]; + | -^^^^^^ + | | + | help: did you mean to return it?: `return` + +error: statement with no effect + --> $DIR/no_effect_return.rs:54:9 + | +LL | ControlFlow::Break::<()>(()); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: did you mean to return it?: `return` + +error: statement with no effect + --> $DIR/no_effect_return.rs:70:9 + | +LL | (); + | -^^ + | | + | help: did you mean to return it?: `return` + +error: statement with no effect + --> $DIR/no_effect_return.rs:78:9 + | +LL | (); + | ^^^ + +error: aborting due to 9 previous errors + diff --git a/tests/ui/no_mangle_with_rust_abi.rs b/tests/ui/no_mangle_with_rust_abi.rs index b32e721110e0..818119f7be57 100644 --- a/tests/ui/no_mangle_with_rust_abi.rs +++ b/tests/ui/no_mangle_with_rust_abi.rs @@ -25,7 +25,7 @@ fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lin 0 } -// Must not run on functions that explicitly opt in to Rust ABI with `extern "Rust"` +// Must not run on functions that explicitly opt in to using the Rust ABI with `extern "Rust"` #[no_mangle] #[rustfmt::skip] extern "Rust" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {} diff --git a/tests/ui/non_expressive_names.rs b/tests/ui/non_expressive_names.rs index 583096ac054a..987a4775ef07 100644 --- a/tests/ui/non_expressive_names.rs +++ b/tests/ui/non_expressive_names.rs @@ -25,9 +25,9 @@ impl MaybeInst { } fn underscores_and_numbers() { - let _1 = 1; //~ERROR Consider a more descriptive name - let ____1 = 1; //~ERROR Consider a more descriptive name - let __1___2 = 12; //~ERROR Consider a more descriptive name + let _1 = 1; //~ERROR: consider choosing a more descriptive name + let ____1 = 1; //~ERROR: consider choosing a more descriptive name + let __1___2 = 12; //~ERROR: consider choosing a more descriptive name let _1_ok = 1; } @@ -48,9 +48,9 @@ struct Bar; impl Bar { fn bar() { - let _1 = 1; - let ____1 = 1; - let __1___2 = 12; + let _1 = 1; //~ERROR: consider choosing a more descriptive name + let ____1 = 1; //~ERROR: consider choosing a more descriptive name + let __1___2 = 12; //~ERROR: consider choosing a more descriptive name let _1_ok = 1; } } diff --git a/tests/ui/non_expressive_names.stderr b/tests/ui/non_expressive_names.stderr index 116d5da8729c..b62748d4989d 100644 --- a/tests/ui/non_expressive_names.stderr +++ b/tests/ui/non_expressive_names.stderr @@ -1,7 +1,7 @@ error: consider choosing a more descriptive name --> $DIR/non_expressive_names.rs:28:9 | -LL | let _1 = 1; //~ERROR Consider a more descriptive name +LL | let _1 = 1; | ^^ | = note: `-D clippy::just-underscores-and-digits` implied by `-D warnings` @@ -9,13 +9,13 @@ LL | let _1 = 1; //~ERROR Consider a more descriptive name error: consider choosing a more descriptive name --> $DIR/non_expressive_names.rs:29:9 | -LL | let ____1 = 1; //~ERROR Consider a more descriptive name +LL | let ____1 = 1; | ^^^^^ error: consider choosing a more descriptive name --> $DIR/non_expressive_names.rs:30:9 | -LL | let __1___2 = 12; //~ERROR Consider a more descriptive name +LL | let __1___2 = 12; | ^^^^^^^ error: consider choosing a more descriptive name diff --git a/tests/ui/non_minimal_cfg.fixed b/tests/ui/non_minimal_cfg.fixed new file mode 100644 index 000000000000..ada3f7cb720e --- /dev/null +++ b/tests/ui/non_minimal_cfg.fixed @@ -0,0 +1,26 @@ +//@run-rustfix + +#![allow(unused)] + +#[cfg(windows)] +fn hermit() {} + +#[cfg(windows)] +fn wasi() {} + +#[cfg(all(unix, not(windows)))] +fn the_end() {} + +<<<<<<< HEAD +<<<<<<< HEAD +#[cfg(any())] +fn any() {} + +======= +>>>>>>> fcf19481a (Add UI test for UNIQUE_CFG_CONDITION) +======= +#[cfg(any())] +fn any() {} + +>>>>>>> dbc76a766 (Add check for empty cfg `all` condition) +fn main() {} diff --git a/tests/ui/non_minimal_cfg.rs b/tests/ui/non_minimal_cfg.rs new file mode 100644 index 000000000000..8bb3688e9942 --- /dev/null +++ b/tests/ui/non_minimal_cfg.rs @@ -0,0 +1,26 @@ +//@run-rustfix + +#![allow(unused)] + +#[cfg(all(windows))] +fn hermit() {} + +#[cfg(any(windows))] +fn wasi() {} + +#[cfg(all(any(unix), all(not(windows))))] +fn the_end() {} + +<<<<<<< HEAD +<<<<<<< HEAD +#[cfg(any())] +fn any() {} + +======= +>>>>>>> fcf19481a (Add UI test for UNIQUE_CFG_CONDITION) +======= +#[cfg(any())] +fn any() {} + +>>>>>>> dbc76a766 (Add check for empty cfg `all` condition) +fn main() {} diff --git a/tests/ui/non_minimal_cfg.stderr b/tests/ui/non_minimal_cfg.stderr new file mode 100644 index 000000000000..cdfd728aa611 --- /dev/null +++ b/tests/ui/non_minimal_cfg.stderr @@ -0,0 +1,28 @@ +error: unneeded sub `cfg` when there is only one condition + --> $DIR/non_minimal_cfg.rs:5:7 + | +LL | #[cfg(all(windows))] + | ^^^^^^^^^^^^ help: try: `windows` + | + = note: `-D clippy::non-minimal-cfg` implied by `-D warnings` + +error: unneeded sub `cfg` when there is only one condition + --> $DIR/non_minimal_cfg.rs:8:7 + | +LL | #[cfg(any(windows))] + | ^^^^^^^^^^^^ help: try: `windows` + +error: unneeded sub `cfg` when there is only one condition + --> $DIR/non_minimal_cfg.rs:11:11 + | +LL | #[cfg(all(any(unix), all(not(windows))))] + | ^^^^^^^^^ help: try: `unix` + +error: unneeded sub `cfg` when there is only one condition + --> $DIR/non_minimal_cfg.rs:11:22 + | +LL | #[cfg(all(any(unix), all(not(windows))))] + | ^^^^^^^^^^^^^^^^^ help: try: `not(windows)` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/non_minimal_cfg2.rs b/tests/ui/non_minimal_cfg2.rs new file mode 100644 index 000000000000..a4c6abce3876 --- /dev/null +++ b/tests/ui/non_minimal_cfg2.rs @@ -0,0 +1,6 @@ +#![allow(unused)] + +#[cfg(all())] +fn all() {} + +fn main() {} diff --git a/tests/ui/non_minimal_cfg2.stderr b/tests/ui/non_minimal_cfg2.stderr new file mode 100644 index 000000000000..2a9a36fbcef3 --- /dev/null +++ b/tests/ui/non_minimal_cfg2.stderr @@ -0,0 +1,10 @@ +error: unneeded sub `cfg` when there is no condition + --> $DIR/non_minimal_cfg2.rs:3:7 + | +LL | #[cfg(all())] + | ^^^^^ + | + = note: `-D clippy::non-minimal-cfg` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/tests/ui/non_octal_unix_permissions.fixed b/tests/ui/non_octal_unix_permissions.fixed index a9b2dcfb0856..e7ca71a325d0 100644 --- a/tests/ui/non_octal_unix_permissions.fixed +++ b/tests/ui/non_octal_unix_permissions.fixed @@ -1,5 +1,9 @@ -// ignore-windows -// run-rustfix +<<<<<<< HEAD +//@ignore-target-windows +======= +//@ignore-windows +>>>>>>> e4f5d83fa (Fixed formatting.) +//@run-rustfix #![warn(clippy::non_octal_unix_permissions)] use std::fs::{DirBuilder, File, OpenOptions, Permissions}; use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt, PermissionsExt}; diff --git a/tests/ui/non_octal_unix_permissions.rs b/tests/ui/non_octal_unix_permissions.rs index 7d2922f494e1..20a562ecaed5 100644 --- a/tests/ui/non_octal_unix_permissions.rs +++ b/tests/ui/non_octal_unix_permissions.rs @@ -1,5 +1,9 @@ -// ignore-windows -// run-rustfix +<<<<<<< HEAD +//@ignore-target-windows +======= +//@ignore-windows +>>>>>>> e4f5d83fa (Fixed formatting.) +//@run-rustfix #![warn(clippy::non_octal_unix_permissions)] use std::fs::{DirBuilder, File, OpenOptions, Permissions}; use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt, PermissionsExt}; diff --git a/tests/ui/nonminimal_bool.rs b/tests/ui/nonminimal_bool.rs index 80cc7c60f56e..e4aa0937b977 100644 --- a/tests/ui/nonminimal_bool.rs +++ b/tests/ui/nonminimal_bool.rs @@ -1,6 +1,7 @@ #![feature(lint_reasons)] -#![allow(unused, clippy::diverging_sub_expression)] +#![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)] #![warn(clippy::nonminimal_bool)] +#![allow(clippy::useless_vec)] fn main() { let a: bool = unimplemented!(); @@ -110,3 +111,17 @@ fn issue_10435() { println!("{}", line!()); } } + +fn issue10836() { + struct Foo(bool); + impl std::ops::Not for Foo { + type Output = bool; + + fn not(self) -> Self::Output { + !self.0 + } + } + + // Should not lint + let _: bool = !!Foo(true); +} diff --git a/tests/ui/nonminimal_bool.stderr b/tests/ui/nonminimal_bool.stderr index 91b5805aa97a..d2e5e0eb8c21 100644 --- a/tests/ui/nonminimal_bool.stderr +++ b/tests/ui/nonminimal_bool.stderr @@ -1,5 +1,5 @@ error: this boolean expression can be simplified - --> $DIR/nonminimal_bool.rs:11:13 + --> $DIR/nonminimal_bool.rs:12:13 | LL | let _ = !true; | ^^^^^ help: try: `false` @@ -7,43 +7,62 @@ LL | let _ = !true; = note: `-D clippy::nonminimal-bool` implied by `-D warnings` error: this boolean expression can be simplified - --> $DIR/nonminimal_bool.rs:12:13 + --> $DIR/nonminimal_bool.rs:13:13 | LL | let _ = !false; | ^^^^^^ help: try: `true` error: this boolean expression can be simplified +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/nonminimal_bool.rs:14:13 +======= --> $DIR/nonminimal_bool.rs:13:13 +>>>>>>> e4927f98f (change booleans file and update tests) +======= + --> $DIR/nonminimal_bool.rs:14:13 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) | LL | let _ = !!a; | ^^^ help: try: `a` error: this boolean expression can be simplified +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> d3534a652 (fix issues 10836) + --> $DIR/nonminimal_bool.rs:15:13 +======= --> $DIR/nonminimal_bool.rs:14:13 +>>>>>>> e4927f98f (change booleans file and update tests) +======= + --> $DIR/nonminimal_bool.rs:15:13 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) | LL | let _ = false || a; | ^^^^^^^^^^ help: try: `a` error: this boolean expression can be simplified - --> $DIR/nonminimal_bool.rs:18:13 + --> $DIR/nonminimal_bool.rs:19:13 | LL | let _ = !(!a && b); | ^^^^^^^^^^ help: try: `a || !b` error: this boolean expression can be simplified - --> $DIR/nonminimal_bool.rs:19:13 + --> $DIR/nonminimal_bool.rs:20:13 | LL | let _ = !(!a || b); | ^^^^^^^^^^ help: try: `a && !b` error: this boolean expression can be simplified - --> $DIR/nonminimal_bool.rs:20:13 + --> $DIR/nonminimal_bool.rs:21:13 | LL | let _ = !a && !(b && c); | ^^^^^^^^^^^^^^^ help: try: `!(a || b && c)` error: this boolean expression can be simplified - --> $DIR/nonminimal_bool.rs:28:13 + --> $DIR/nonminimal_bool.rs:29:13 | LL | let _ = a == b && c == 5 && a == b; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +75,7 @@ LL | let _ = a == b && c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> $DIR/nonminimal_bool.rs:29:13 + --> $DIR/nonminimal_bool.rs:30:13 | LL | let _ = a == b || c == 5 || a == b; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,7 +88,7 @@ LL | let _ = a == b || c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> $DIR/nonminimal_bool.rs:30:13 + --> $DIR/nonminimal_bool.rs:31:13 | LL | let _ = a == b && c == 5 && b == a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -82,7 +101,7 @@ LL | let _ = a == b && c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> $DIR/nonminimal_bool.rs:31:13 + --> $DIR/nonminimal_bool.rs:32:13 | LL | let _ = a != b || !(a != b || c == d); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -95,7 +114,7 @@ LL | let _ = a != b || c != d; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> $DIR/nonminimal_bool.rs:32:13 + --> $DIR/nonminimal_bool.rs:33:13 | LL | let _ = a != b && !(a != b && c == d); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -108,7 +127,7 @@ LL | let _ = a != b && c != d; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> $DIR/nonminimal_bool.rs:62:8 + --> $DIR/nonminimal_bool.rs:63:8 | LL | if matches!(true, true) && true { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(true, true)` diff --git a/tests/ui/nonminimal_bool_methods.fixed b/tests/ui/nonminimal_bool_methods.fixed index aad44089de49..fbeaba14b120 100644 --- a/tests/ui/nonminimal_bool_methods.fixed +++ b/tests/ui/nonminimal_bool_methods.fixed @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)] +======= #![allow(unused, clippy::diverging_sub_expression)] +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::nonminimal_bool)] fn methods_with_negation() { diff --git a/tests/ui/nonminimal_bool_methods.rs b/tests/ui/nonminimal_bool_methods.rs index b9074da84270..e475f46f18f9 100644 --- a/tests/ui/nonminimal_bool_methods.rs +++ b/tests/ui/nonminimal_bool_methods.rs @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)] +======= #![allow(unused, clippy::diverging_sub_expression)] +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::nonminimal_bool)] fn methods_with_negation() { diff --git a/tests/ui/numbered_fields.fixed b/tests/ui/numbered_fields.fixed index 68c987eb4c67..a52845e53a4c 100644 --- a/tests/ui/numbered_fields.fixed +++ b/tests/ui/numbered_fields.fixed @@ -1,4 +1,4 @@ -//run-rustfix +//@run-rustfix #![warn(clippy::init_numbered_fields)] #![allow(unused_tuple_struct_fields)] diff --git a/tests/ui/numbered_fields.rs b/tests/ui/numbered_fields.rs index 2ef4fb4de537..ca93f7dce59a 100644 --- a/tests/ui/numbered_fields.rs +++ b/tests/ui/numbered_fields.rs @@ -1,4 +1,4 @@ -//run-rustfix +//@run-rustfix #![warn(clippy::init_numbered_fields)] #![allow(unused_tuple_struct_fields)] diff --git a/tests/ui/numbered_fields.stderr b/tests/ui/numbered_fields.stderr index 60c0d7898063..26f7ad9048b8 100644 --- a/tests/ui/numbered_fields.stderr +++ b/tests/ui/numbered_fields.stderr @@ -7,7 +7,7 @@ LL | | 0: 1u32, LL | | 1: 42, LL | | 2: 23u8, LL | | }; - | |_____^ help: try this instead: `TupleStruct(1u32, 42, 23u8)` + | |_____^ help: try: `TupleStruct(1u32, 42, 23u8)` | = note: `-D clippy::init-numbered-fields` implied by `-D warnings` @@ -20,7 +20,7 @@ LL | | 0: 1u32, LL | | 2: 2u8, LL | | 1: 3u32, LL | | }; - | |_____^ help: try this instead: `TupleStruct(1u32, 3u32, 2u8)` + | |_____^ help: try: `TupleStruct(1u32, 3u32, 2u8)` error: aborting due to 2 previous errors diff --git a/tests/ui/obfuscated_if_else.fixed b/tests/ui/obfuscated_if_else.fixed index 62d932c2c6b7..9e4f97253f84 100644 --- a/tests/ui/obfuscated_if_else.fixed +++ b/tests/ui/obfuscated_if_else.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::obfuscated_if_else)] diff --git a/tests/ui/obfuscated_if_else.rs b/tests/ui/obfuscated_if_else.rs index 273be9092a74..c2351d64c1c5 100644 --- a/tests/ui/obfuscated_if_else.rs +++ b/tests/ui/obfuscated_if_else.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::obfuscated_if_else)] diff --git a/tests/ui/octal_escapes.stderr b/tests/ui/octal_escapes.stderr index aa362e96321b..63fdfe486e81 100644 --- a/tests/ui/octal_escapes.stderr +++ b/tests/ui/octal_escapes.stderr @@ -34,17 +34,17 @@ LL | let _bad2 = b"/x0033[0m"; error: octal-looking escape in string literal --> $DIR/octal_escapes.rs:6:17 | -LL | let _bad3 = "//033[0m"; +LL | let _bad3 = "///033[0m"; | ^^^^^^^^^^^ | = help: octal escapes are not supported, `/0` is always a null character help: if an octal escape was intended, use the hexadecimal representation instead | -LL | let _bad3 = "//x1b[0m"; +LL | let _bad3 = "///x1b[0m"; | ~~~~~~~~~~~ help: if the null character is intended, disambiguate using | -LL | let _bad3 = "//x0033[0m"; +LL | let _bad3 = "///x0033[0m"; | ~~~~~~~~~~~~~ error: octal-looking escape in string literal diff --git a/tests/ui/ok_expect.rs b/tests/ui/ok_expect.rs index ff68d38c73bf..2047ee689d95 100644 --- a/tests/ui/ok_expect.rs +++ b/tests/ui/ok_expect.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unnecessary_literal_unwrap)] + use std::io; struct MyError(()); // doesn't implement Debug diff --git a/tests/ui/ok_expect.stderr b/tests/ui/ok_expect.stderr index 6c40adbb53dc..ab9df26ebc37 100644 --- a/tests/ui/ok_expect.stderr +++ b/tests/ui/ok_expect.stderr @@ -1,5 +1,5 @@ error: called `ok().expect()` on a `Result` value - --> $DIR/ok_expect.rs:14:5 + --> $DIR/ok_expect.rs:16:5 | LL | res.ok().expect("disaster!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | res.ok().expect("disaster!"); = note: `-D clippy::ok-expect` implied by `-D warnings` error: called `ok().expect()` on a `Result` value - --> $DIR/ok_expect.rs:20:5 + --> $DIR/ok_expect.rs:22:5 | LL | res3.ok().expect("whoof"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | res3.ok().expect("whoof"); = help: you can call `expect()` directly on the `Result` error: called `ok().expect()` on a `Result` value - --> $DIR/ok_expect.rs:22:5 + --> $DIR/ok_expect.rs:24:5 | LL | res4.ok().expect("argh"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | res4.ok().expect("argh"); = help: you can call `expect()` directly on the `Result` error: called `ok().expect()` on a `Result` value - --> $DIR/ok_expect.rs:24:5 + --> $DIR/ok_expect.rs:26:5 | LL | res5.ok().expect("oops"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | res5.ok().expect("oops"); = help: you can call `expect()` directly on the `Result` error: called `ok().expect()` on a `Result` value - --> $DIR/ok_expect.rs:26:5 + --> $DIR/ok_expect.rs:28:5 | LL | res6.ok().expect("meh"); | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/option_as_ref_deref.fixed b/tests/ui/option_as_ref_deref.fixed index d124d133faa2..4d1a6a1ab98d 100644 --- a/tests/ui/option_as_ref_deref.fixed +++ b/tests/ui/option_as_ref_deref.fixed @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix -#![allow(unused, clippy::redundant_clone)] +#![allow(unused, clippy::redundant_clone, clippy::useless_vec)] #![warn(clippy::option_as_ref_deref)] use std::ffi::{CString, OsString}; diff --git a/tests/ui/option_as_ref_deref.rs b/tests/ui/option_as_ref_deref.rs index 86e354c6716b..66d5a1250360 100644 --- a/tests/ui/option_as_ref_deref.rs +++ b/tests/ui/option_as_ref_deref.rs @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix -#![allow(unused, clippy::redundant_clone)] +#![allow(unused, clippy::redundant_clone, clippy::useless_vec)] #![warn(clippy::option_as_ref_deref)] use std::ffi::{CString, OsString}; diff --git a/tests/ui/option_env_unwrap.rs b/tests/ui/option_env_unwrap.rs index 9a56cf40d8a7..9e1964b57ec3 100644 --- a/tests/ui/option_env_unwrap.rs +++ b/tests/ui/option_env_unwrap.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::option_env_unwrap)] #![allow(clippy::map_flatten)] diff --git a/tests/ui/option_filter_map.fixed b/tests/ui/option_filter_map.fixed index b20f73f3110d..93c250cfa735 100644 --- a/tests/ui/option_filter_map.fixed +++ b/tests/ui/option_filter_map.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_filter_map)] #![allow(clippy::map_flatten)] diff --git a/tests/ui/option_filter_map.rs b/tests/ui/option_filter_map.rs index 7abaaa0fb83b..2c5f03250b98 100644 --- a/tests/ui/option_filter_map.rs +++ b/tests/ui/option_filter_map.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_filter_map)] #![allow(clippy::map_flatten)] diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed index 0456005dce49..72de589a5a77 100644 --- a/tests/ui/option_if_let_else.fixed +++ b/tests/ui/option_if_let_else.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_if_let_else)] #![allow( unused_tuple_struct_fields, @@ -25,7 +25,7 @@ fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> { fn unop_bad(string: &Option<&str>, mut num: Option) { let _ = string.map_or(0, |s| s.len()); let _ = num.as_ref().map_or(&0, |s| s); - let _ = num.as_mut().map_or(&mut 0, |s| { + let _ = num.as_mut().map_or(&0, |s| { *s += 1; s }); @@ -34,7 +34,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { s += 1; s }); - let _ = num.as_mut().map_or(&mut 0, |s| { + let _ = num.as_mut().map_or(&0, |s| { *s += 1; s }); @@ -92,12 +92,21 @@ fn pattern_to_vec(pattern: &str) -> Vec { .collect::>() } +// #10335 +fn test_result_impure_else(variable: Result) { + variable.map_or_else(|_| { + println!("Err"); + }, |binding| { + println!("Ok {binding}"); + }) +} + enum DummyEnum { One(u8), Two, } -// should not warn since there is a compled complex subpat +// should not warn since there is a complex subpat // see #7991 fn complex_subpat() -> DummyEnum { let x = Some(DummyEnum::One(1)); @@ -113,6 +122,7 @@ fn main() { unop_bad(&None, None); let _ = longer_body(None); test_map_or_else(None); + test_result_impure_else(Ok(42)); let _ = negative_tests(None); let _ = impure_else(None); @@ -198,3 +208,27 @@ fn issue9742() -> Option<&'static str> { _ => None, } } + +mod issue10729 { +<<<<<<< HEAD +<<<<<<< HEAD + #![allow(clippy::unit_arg, dead_code)] +======= + #![allow(clippy::unit_arg)] +>>>>>>> 733a9ea6b ([`option_if_let_else`]: suggest `.as_ref()` if `&Option<_>`) +======= + #![allow(clippy::unit_arg, dead_code)] +>>>>>>> cee4c4169 (allow dead code in the test) + + pub fn reproduce(initial: &Option) { + // 👇 needs `.as_ref()` because initial is an `&Option<_>` + initial.as_ref().map_or({}, |value| do_something(value)) + } + + pub fn reproduce2(initial: &mut Option) { + initial.as_mut().map_or({}, |value| do_something2(value)) + } + + fn do_something(_value: &str) {} + fn do_something2(_value: &mut str) {} +} diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index 23b148752cbf..e2f0078ec025 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_if_let_else)] #![allow( unused_tuple_struct_fields, @@ -33,7 +33,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { *s += 1; s } else { - &mut 0 + &0 }; let _ = if let Some(ref s) = num { s } else { &0 }; let _ = if let Some(mut s) = num { @@ -46,7 +46,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { *s += 1; s } else { - &mut 0 + &0 }; } @@ -115,12 +115,21 @@ fn pattern_to_vec(pattern: &str) -> Vec { .collect::>() } +// #10335 +fn test_result_impure_else(variable: Result) { + if let Ok(binding) = variable { + println!("Ok {binding}"); + } else { + println!("Err"); + } +} + enum DummyEnum { One(u8), Two, } -// should not warn since there is a compled complex subpat +// should not warn since there is a complex subpat // see #7991 fn complex_subpat() -> DummyEnum { let x = Some(DummyEnum::One(1)); @@ -136,6 +145,7 @@ fn main() { unop_bad(&None, None); let _ = longer_body(None); test_map_or_else(None); + test_result_impure_else(Ok(42)); let _ = negative_tests(None); let _ = impure_else(None); @@ -239,3 +249,33 @@ fn issue9742() -> Option<&'static str> { _ => None, } } + +mod issue10729 { +<<<<<<< HEAD +<<<<<<< HEAD + #![allow(clippy::unit_arg, dead_code)] +======= + #![allow(clippy::unit_arg)] +>>>>>>> 733a9ea6b ([`option_if_let_else`]: suggest `.as_ref()` if `&Option<_>`) +======= + #![allow(clippy::unit_arg, dead_code)] +>>>>>>> cee4c4169 (allow dead code in the test) + + pub fn reproduce(initial: &Option) { + // 👇 needs `.as_ref()` because initial is an `&Option<_>` + match initial { + Some(value) => do_something(value), + None => {}, + } + } + + pub fn reproduce2(initial: &mut Option) { + match initial { + Some(value) => do_something2(value), + None => {}, + } + } + + fn do_something(_value: &str) {} + fn do_something2(_value: &mut str) {} +} diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr index a5dbf6e1f221..293c92e35a21 100644 --- a/tests/ui/option_if_let_else.stderr +++ b/tests/ui/option_if_let_else.stderr @@ -30,13 +30,13 @@ LL | let _ = if let Some(s) = &mut num { LL | | *s += 1; LL | | s LL | | } else { -LL | | &mut 0 +LL | | &0 LL | | }; | |_____^ | help: try | -LL ~ let _ = num.as_mut().map_or(&mut 0, |s| { +LL ~ let _ = num.as_mut().map_or(&0, |s| { LL + *s += 1; LL + s LL ~ }); @@ -76,13 +76,13 @@ LL | let _ = if let Some(ref mut s) = num { LL | | *s += 1; LL | | s LL | | } else { -LL | | &mut 0 +LL | | &0 LL | | }; | |_____^ | help: try | -LL ~ let _ = num.as_mut().map_or(&mut 0, |s| { +LL ~ let _ = num.as_mut().map_or(&0, |s| { LL + *s += 1; LL + s LL ~ }); @@ -152,14 +152,33 @@ LL | | vec![s.to_string()] LL | | } | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])` +error: use Option::map_or_else instead of an if let/else + --> $DIR/option_if_let_else.rs:120:5 + | +LL | / if let Ok(binding) = variable { +LL | | println!("Ok {binding}"); +LL | | } else { +LL | | println!("Err"); +LL | | } + | |_____^ + | +help: try + | +LL ~ variable.map_or_else(|_| { +LL + println!("Err"); +LL + }, |binding| { +LL + println!("Ok {binding}"); +LL + }) + | + error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:133:13 + --> $DIR/option_if_let_else.rs:142:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:142:13 + --> $DIR/option_if_let_else.rs:152:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -181,13 +200,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:170:13 + --> $DIR/option_if_let_else.rs:180:13 | LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:174:13 + --> $DIR/option_if_let_else.rs:184:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -207,7 +226,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:213:13 + --> $DIR/option_if_let_else.rs:223:13 | LL | let _ = match s { | _____________^ @@ -217,7 +236,7 @@ LL | | }; | |_____^ help: try: `s.map_or(1, |string| string.len())` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:217:13 + --> $DIR/option_if_let_else.rs:227:13 | LL | let _ = match Some(10) { | _____________^ @@ -227,7 +246,7 @@ LL | | }; | |_____^ help: try: `Some(10).map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:223:13 + --> $DIR/option_if_let_else.rs:233:13 | LL | let _ = match res { | _____________^ @@ -237,7 +256,7 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:227:13 + --> $DIR/option_if_let_else.rs:237:13 | LL | let _ = match res { | _____________^ @@ -247,10 +266,52 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:231:13 + --> $DIR/option_if_let_else.rs:241:13 | LL | let _ = if let Ok(a) = res { a + 1 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)` -error: aborting due to 20 previous errors +<<<<<<< HEAD +<<<<<<< HEAD +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:258:9 +======= +error: use Option::map_or instead of an if let/else +<<<<<<< HEAD + --> $DIR/option_if_let_else.rs:260:9 +>>>>>>> 733a9ea6b ([`option_if_let_else`]: suggest `.as_ref()` if `&Option<_>`) +======= + --> $DIR/option_if_let_else.rs:258:9 +>>>>>>> cee4c4169 (allow dead code in the test) + | +LL | / match initial { +LL | | Some(value) => do_something(value), +LL | | None => {}, +LL | | } + | |_________^ help: try: `initial.as_ref().map_or({}, |value| do_something(value))` + +error: use Option::map_or instead of an if let/else +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/option_if_let_else.rs:265:9 +======= + --> $DIR/option_if_let_else.rs:267:9 +>>>>>>> 733a9ea6b ([`option_if_let_else`]: suggest `.as_ref()` if `&Option<_>`) +======= + --> $DIR/option_if_let_else.rs:265:9 +>>>>>>> cee4c4169 (allow dead code in the test) + | +LL | / match initial { +LL | | Some(value) => do_something2(value), +LL | | None => {}, +LL | | } + | |_________^ help: try: `initial.as_mut().map_or({}, |value| do_something2(value))` + +error: aborting due to 23 previous errors +<<<<<<< HEAD +======= +error: aborting due to 21 previous errors +>>>>>>> d80ca09f5 (Fix: Some suggestions generated by the option_if_let_else lint did not compile) +======= +>>>>>>> 733a9ea6b ([`option_if_let_else`]: suggest `.as_ref()` if `&Option<_>`) diff --git a/tests/ui/option_map_or_none.fixed b/tests/ui/option_map_or_none.fixed index 04bfac7735fa..501757647bfb 100644 --- a/tests/ui/option_map_or_none.fixed +++ b/tests/ui/option_map_or_none.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::bind_instead_of_map)] diff --git a/tests/ui/option_map_or_none.rs b/tests/ui/option_map_or_none.rs index bb84f8a48f45..4d8704e737da 100644 --- a/tests/ui/option_map_or_none.rs +++ b/tests/ui/option_map_or_none.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::bind_instead_of_map)] diff --git a/tests/ui/option_map_unit_fn_fixable.fixed b/tests/ui/option_map_unit_fn_fixable.fixed index 00264dcceaa8..8f64451edf36 100644 --- a/tests/ui/option_map_unit_fn_fixable.fixed +++ b/tests/ui/option_map_unit_fn_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_map_unit_fn)] #![allow(unused)] #![allow(clippy::uninlined_format_args, clippy::unnecessary_wraps)] diff --git a/tests/ui/option_map_unit_fn_fixable.rs b/tests/ui/option_map_unit_fn_fixable.rs index f3363ebce54e..2bf7a8e0f7d4 100644 --- a/tests/ui/option_map_unit_fn_fixable.rs +++ b/tests/ui/option_map_unit_fn_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_map_unit_fn)] #![allow(unused)] #![allow(clippy::uninlined_format_args, clippy::unnecessary_wraps)] diff --git a/tests/ui/option_map_unit_fn_fixable.stderr b/tests/ui/option_map_unit_fn_fixable.stderr index 0305387b9f8a..5be5f10b0177 100644 --- a/tests/ui/option_map_unit_fn_fixable.stderr +++ b/tests/ui/option_map_unit_fn_fixable.stderr @@ -4,7 +4,7 @@ error: called `map(f)` on an `Option` value where `f` is a function that returns LL | x.field.map(do_nothing); | ^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(x_field) = x.field { do_nothing(x_field) }` + | help: try: `if let Some(x_field) = x.field { do_nothing(x_field) }` | = note: `-D clippy::option-map-unit-fn` implied by `-D warnings` @@ -14,7 +14,7 @@ error: called `map(f)` on an `Option` value where `f` is a function that returns LL | x.field.map(do_nothing); | ^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(x_field) = x.field { do_nothing(x_field) }` + | help: try: `if let Some(x_field) = x.field { do_nothing(x_field) }` error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:42:5 @@ -22,7 +22,7 @@ error: called `map(f)` on an `Option` value where `f` is a function that returns LL | x.field.map(diverge); | ^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(x_field) = x.field { diverge(x_field) }` + | help: try: `if let Some(x_field) = x.field { diverge(x_field) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:48:5 @@ -30,7 +30,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| x.do_option_nothing(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { x.do_option_nothing(value + captured) }` + | help: try: `if let Some(value) = x.field { x.do_option_nothing(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:50:5 @@ -38,7 +38,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| { x.do_option_plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { x.do_option_plus_one(value + captured); }` + | help: try: `if let Some(value) = x.field { x.do_option_plus_one(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:53:5 @@ -46,7 +46,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| do_nothing(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { do_nothing(value + captured) }` + | help: try: `if let Some(value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:55:5 @@ -54,7 +54,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| { do_nothing(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { do_nothing(value + captured) }` + | help: try: `if let Some(value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:57:5 @@ -62,7 +62,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| { do_nothing(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { do_nothing(value + captured); }` + | help: try: `if let Some(value) = x.field { do_nothing(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:59:5 @@ -70,7 +70,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| { { do_nothing(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { do_nothing(value + captured); }` + | help: try: `if let Some(value) = x.field { do_nothing(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:62:5 @@ -78,7 +78,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| diverge(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { diverge(value + captured) }` + | help: try: `if let Some(value) = x.field { diverge(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:64:5 @@ -86,7 +86,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| { diverge(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { diverge(value + captured) }` + | help: try: `if let Some(value) = x.field { diverge(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:66:5 @@ -94,7 +94,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| { diverge(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { diverge(value + captured); }` + | help: try: `if let Some(value) = x.field { diverge(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:68:5 @@ -102,7 +102,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| { { diverge(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { diverge(value + captured); }` + | help: try: `if let Some(value) = x.field { diverge(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:73:5 @@ -110,7 +110,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| { let y = plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { let y = plus_one(value + captured); }` + | help: try: `if let Some(value) = x.field { let y = plus_one(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:75:5 @@ -118,7 +118,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| { plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { plus_one(value + captured); }` + | help: try: `if let Some(value) = x.field { plus_one(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:77:5 @@ -126,7 +126,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|value| { { plus_one(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = x.field { plus_one(value + captured); }` + | help: try: `if let Some(value) = x.field { plus_one(value + captured); }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:80:5 @@ -134,7 +134,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | x.field.map(|ref value| { do_nothing(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(ref value) = x.field { do_nothing(value + captured) }` + | help: try: `if let Some(ref value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:82:5 @@ -142,7 +142,7 @@ error: called `map(f)` on an `Option` value where `f` is a function that returns LL | option().map(do_nothing); | ^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(a) = option() { do_nothing(a) }` + | help: try: `if let Some(a) = option() { do_nothing(a) }` error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()` --> $DIR/option_map_unit_fn_fixable.rs:84:5 @@ -150,7 +150,7 @@ error: called `map(f)` on an `Option` value where `f` is a closure that returns LL | option().map(|value| println!("{:?}", value)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Some(value) = option() { println!("{:?}", value) }` + | help: try: `if let Some(value) = option() { println!("{:?}", value) }` error: aborting due to 19 previous errors diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed index be9a65506e13..46e9448a3c88 100644 --- a/tests/ui/or_fun_call.fixed +++ b/tests/ui/or_fun_call.fixed @@ -1,10 +1,22 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::or_fun_call)] #![allow(dead_code)] -#![allow(clippy::borrow_as_ptr, clippy::uninlined_format_args, clippy::unnecessary_wraps)] - -use std::collections::BTreeMap; -use std::collections::HashMap; +#![allow( + clippy::borrow_as_ptr, + clippy::uninlined_format_args, + clippy::unnecessary_wraps, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::unnecessary_literal_unwrap, +======= +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + clippy::unnecessary_literal_unwrap, +>>>>>>> bfd5abad4 (Fix all the other tests) + clippy::useless_vec +)] + +use std::collections::{BTreeMap, HashMap}; use std::time::Duration; /// Checks implementation of the `OR_FUN_CALL` lint. diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs index 628c97046389..41ea16b80764 100644 --- a/tests/ui/or_fun_call.rs +++ b/tests/ui/or_fun_call.rs @@ -1,10 +1,22 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::or_fun_call)] #![allow(dead_code)] -#![allow(clippy::borrow_as_ptr, clippy::uninlined_format_args, clippy::unnecessary_wraps)] - -use std::collections::BTreeMap; -use std::collections::HashMap; +#![allow( + clippy::borrow_as_ptr, + clippy::uninlined_format_args, + clippy::unnecessary_wraps, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::unnecessary_literal_unwrap, +======= +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + clippy::unnecessary_literal_unwrap, +>>>>>>> bfd5abad4 (Fix all the other tests) + clippy::useless_vec +)] + +use std::collections::{BTreeMap, HashMap}; use std::time::Duration; /// Checks implementation of the `OR_FUN_CALL` lint. diff --git a/tests/ui/or_fun_call.stderr b/tests/ui/or_fun_call.stderr index ba3001db7a5f..d0f0c2cca227 100644 --- a/tests/ui/or_fun_call.stderr +++ b/tests/ui/or_fun_call.stderr @@ -1,172 +1,508 @@ error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:48:22 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:54:22 +======= + --> $DIR/or_fun_call.rs:53:22 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:54:22 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:53:22 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | with_constructor.unwrap_or(make()); - | ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(make)` + | ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(make)` | = note: `-D clippy::or-fun-call` implied by `-D warnings` error: use of `unwrap_or` followed by a call to `new` - --> $DIR/or_fun_call.rs:51:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:57:14 +======= + --> $DIR/or_fun_call.rs:56:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:57:14 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:56:14 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | with_new.unwrap_or(Vec::new()); - | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:54:21 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:60:21 +======= + --> $DIR/or_fun_call.rs:59:21 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:60:21 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:59:21 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | with_const_args.unwrap_or(Vec::with_capacity(12)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| Vec::with_capacity(12))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Vec::with_capacity(12))` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:57:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:63:14 +======= + --> $DIR/or_fun_call.rs:62:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:63:14 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:62:14 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | with_err.unwrap_or(make()); - | ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| make())` + | ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| make())` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:60:19 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:66:19 +======= + --> $DIR/or_fun_call.rs:65:19 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:66:19 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:65:19 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | with_err_args.unwrap_or(Vec::with_capacity(12)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| Vec::with_capacity(12))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| Vec::with_capacity(12))` error: use of `unwrap_or` followed by a call to `default` - --> $DIR/or_fun_call.rs:63:24 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:69:24 +======= + --> $DIR/or_fun_call.rs:68:24 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:69:24 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:68:24 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | with_default_trait.unwrap_or(Default::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` followed by a call to `default` - --> $DIR/or_fun_call.rs:66:23 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:72:23 +======= + --> $DIR/or_fun_call.rs:71:23 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:72:23 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:71:23 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | with_default_type.unwrap_or(u64::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:69:18 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:75:18 +======= + --> $DIR/or_fun_call.rs:74:18 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:75:18 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:74:18 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | self_default.unwrap_or(::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(::default)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(::default)` error: use of `unwrap_or` followed by a call to `default` - --> $DIR/or_fun_call.rs:72:18 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:78:18 +======= + --> $DIR/or_fun_call.rs:77:18 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:78:18 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:77:18 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | real_default.unwrap_or(::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` followed by a call to `new` - --> $DIR/or_fun_call.rs:75:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:81:14 +======= + --> $DIR/or_fun_call.rs:80:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:81:14 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:80:14 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | with_vec.unwrap_or(vec![]); - | ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` + | ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:78:21 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:84:21 +======= + --> $DIR/or_fun_call.rs:83:21 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:84:21 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:83:21 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | without_default.unwrap_or(Foo::new()); - | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(Foo::new)` + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(Foo::new)` error: use of `or_insert` followed by a call to `new` - --> $DIR/or_fun_call.rs:81:19 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:87:19 +======= + --> $DIR/or_fun_call.rs:86:19 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:87:19 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:86:19 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | map.entry(42).or_insert(String::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_default()` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` followed by a call to `new` - --> $DIR/or_fun_call.rs:84:23 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:90:23 +======= + --> $DIR/or_fun_call.rs:89:23 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:90:23 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:89:23 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | map_vec.entry(42).or_insert(vec![]); - | ^^^^^^^^^^^^^^^^^ help: try this: `or_default()` + | ^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` followed by a call to `new` - --> $DIR/or_fun_call.rs:87:21 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:93:21 +======= + --> $DIR/or_fun_call.rs:92:21 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:93:21 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:92:21 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | btree.entry(42).or_insert(String::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_default()` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` followed by a call to `new` - --> $DIR/or_fun_call.rs:90:25 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:96:25 +======= + --> $DIR/or_fun_call.rs:95:25 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:96:25 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:95:25 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | btree_vec.entry(42).or_insert(vec![]); - | ^^^^^^^^^^^^^^^^^ help: try this: `or_default()` + | ^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `unwrap_or` followed by a call to `new` - --> $DIR/or_fun_call.rs:93:21 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:99:21 +======= + --> $DIR/or_fun_call.rs:98:21 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:99:21 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:98:21 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | let _ = stringy.unwrap_or(String::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:101:21 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:107:21 +======= + --> $DIR/or_fun_call.rs:106:21 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:107:21 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:106:21 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | let _ = Some(1).unwrap_or(map[&1]); - | ^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| map[&1])` + | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:103:21 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:109:21 +======= + --> $DIR/or_fun_call.rs:108:21 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:109:21 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:108:21 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | let _ = Some(1).unwrap_or(map[&1]); - | ^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| map[&1])` + | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])` error: use of `or` followed by a function call - --> $DIR/or_fun_call.rs:127:35 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:133:35 +======= + --> $DIR/or_fun_call.rs:132:35 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:133:35 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:132:35 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | let _ = Some("a".to_string()).or(Some("b".to_string())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some("b".to_string()))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_else(|| Some("b".to_string()))` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:166:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:172:14 +======= + --> $DIR/or_fun_call.rs:171:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:172:14 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:171:14 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | None.unwrap_or(ptr_to_ref(s)); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| ptr_to_ref(s))` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| ptr_to_ref(s))` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:172:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:178:14 +======= + --> $DIR/or_fun_call.rs:177:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:178:14 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:177:14 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | None.unwrap_or(unsafe { ptr_to_ref(s) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:174:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:180:14 +======= + --> $DIR/or_fun_call.rs:179:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:180:14 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:179:14 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | None.unwrap_or( unsafe { ptr_to_ref(s) } ); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })` error: use of `unwrap_or` followed by a call to `new` - --> $DIR/or_fun_call.rs:188:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:194:14 +======= + --> $DIR/or_fun_call.rs:193:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:194:14 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:193:14 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | .unwrap_or(String::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` followed by a call to `new` - --> $DIR/or_fun_call.rs:201:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:207:14 +======= + --> $DIR/or_fun_call.rs:206:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:207:14 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:206:14 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | .unwrap_or(String::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` followed by a call to `new` - --> $DIR/or_fun_call.rs:213:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:219:14 +======= + --> $DIR/or_fun_call.rs:218:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:219:14 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:218:14 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | .unwrap_or(String::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` followed by a call to `new` - --> $DIR/or_fun_call.rs:224:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:230:10 +======= + --> $DIR/or_fun_call.rs:229:10 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:230:10 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:229:10 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | .unwrap_or(String::new()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `map_or` followed by a function call - --> $DIR/or_fun_call.rs:249:25 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:255:25 +======= + --> $DIR/or_fun_call.rs:254:25 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:255:25 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:254:25 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | let _ = Some(4).map_or(g(), |v| v); - | ^^^^^^^^^^^^^^^^^^ help: try this: `map_or_else(g, |v| v)` + | ^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(g, |v| v)` error: use of `map_or` followed by a function call - --> $DIR/or_fun_call.rs:250:25 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/or_fun_call.rs:256:25 +======= + --> $DIR/or_fun_call.rs:255:25 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/or_fun_call.rs:256:25 +>>>>>>> bfd5abad4 (Fix all the other tests) +======= + --> $DIR/or_fun_call.rs:255:25 +>>>>>>> 2811effe3 (Add `imports_granularity = "Module"` to rustfmt.toml) | LL | let _ = Some(4).map_or(g(), f); - | ^^^^^^^^^^^^^^ help: try this: `map_or_else(g, f)` + | ^^^^^^^^^^^^^^ help: try: `map_or_else(g, f)` error: aborting due to 28 previous errors diff --git a/tests/ui/or_then_unwrap.fixed b/tests/ui/or_then_unwrap.fixed index 844cc4b7a092..773dfc3c5d14 100644 --- a/tests/ui/or_then_unwrap.fixed +++ b/tests/ui/or_then_unwrap.fixed @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::or_then_unwrap)] -#![allow(clippy::map_identity, clippy::let_unit_value)] +#![allow(clippy::map_identity, clippy::let_unit_value, clippy::unnecessary_literal_unwrap)] struct SomeStruct; impl SomeStruct { diff --git a/tests/ui/or_then_unwrap.rs b/tests/ui/or_then_unwrap.rs index 1528ef9be964..5867e014878e 100644 --- a/tests/ui/or_then_unwrap.rs +++ b/tests/ui/or_then_unwrap.rs @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::or_then_unwrap)] -#![allow(clippy::map_identity, clippy::let_unit_value)] +#![allow(clippy::map_identity, clippy::let_unit_value, clippy::unnecessary_literal_unwrap)] struct SomeStruct; impl SomeStruct { diff --git a/tests/ui/or_then_unwrap.stderr b/tests/ui/or_then_unwrap.stderr index da88154c59f7..2a1a52407dc3 100644 --- a/tests/ui/or_then_unwrap.stderr +++ b/tests/ui/or_then_unwrap.stderr @@ -2,7 +2,7 @@ error: found `.or(Some(…)).unwrap()` --> $DIR/or_then_unwrap.rs:24:20 | LL | let _ = option.or(Some("fallback")).unwrap(); // should trigger lint - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or("fallback")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")` | = note: `-D clippy::or-then-unwrap` implied by `-D warnings` @@ -10,13 +10,13 @@ error: found `.or(Ok(…)).unwrap()` --> $DIR/or_then_unwrap.rs:27:20 | LL | let _ = result.or::<&str>(Ok("fallback")).unwrap(); // should trigger lint - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or("fallback")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")` error: found `.or(Some(…)).unwrap()` --> $DIR/or_then_unwrap.rs:31:31 | LL | let _ = option.map(|v| v).or(Some("fallback")).unwrap().to_string().chars(); // should trigger lint - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or("fallback")` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")` error: aborting due to 3 previous errors diff --git a/tests/ui/overflow_check_conditional.rs b/tests/ui/overflow_check_conditional.rs index e1e30114081e..14a6b98d07d1 100644 --- a/tests/ui/overflow_check_conditional.rs +++ b/tests/ui/overflow_check_conditional.rs @@ -1,4 +1,5 @@ #![warn(clippy::overflow_check_conditional)] +#![allow(clippy::needless_if)] fn test(a: u32, b: u32, c: u32) { if a + b < a {} diff --git a/tests/ui/overflow_check_conditional.stderr b/tests/ui/overflow_check_conditional.stderr index 92d1d8ef911e..3ec2298f828a 100644 --- a/tests/ui/overflow_check_conditional.stderr +++ b/tests/ui/overflow_check_conditional.stderr @@ -1,5 +1,5 @@ error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:4:8 + --> $DIR/overflow_check_conditional.rs:5:8 | LL | if a + b < a {} | ^^^^^^^^^ @@ -7,43 +7,43 @@ LL | if a + b < a {} = note: `-D clippy::overflow-check-conditional` implied by `-D warnings` error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:5:8 + --> $DIR/overflow_check_conditional.rs:6:8 | LL | if a > a + b {} | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:6:8 + --> $DIR/overflow_check_conditional.rs:7:8 | LL | if a + b < b {} | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:7:8 + --> $DIR/overflow_check_conditional.rs:8:8 | LL | if b > a + b {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:8:8 + --> $DIR/overflow_check_conditional.rs:9:8 | LL | if a - b > b {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:9:8 + --> $DIR/overflow_check_conditional.rs:10:8 | LL | if b < a - b {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:10:8 + --> $DIR/overflow_check_conditional.rs:11:8 | LL | if a - b > a {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:11:8 + --> $DIR/overflow_check_conditional.rs:12:8 | LL | if a < a - b {} | ^^^^^^^^^ diff --git a/tests/ui/panic_in_result_fn.stderr b/tests/ui/panic_in_result_fn.stderr index 97787bc84e2c..b758fc238124 100644 --- a/tests/ui/panic_in_result_fn.stderr +++ b/tests/ui/panic_in_result_fn.stderr @@ -1,4 +1,4 @@ -error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result` +error: used `panic!()` or assertion in a function that returns `Result` --> $DIR/panic_in_result_fn.rs:6:5 | LL | / fn result_with_panic() -> Result // should emit lint @@ -7,7 +7,7 @@ LL | | panic!("error"); LL | | } | |_____^ | - = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing + = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking --> $DIR/panic_in_result_fn.rs:8:9 | @@ -15,55 +15,7 @@ LL | panic!("error"); | ^^^^^^^^^^^^^^^ = note: `-D clippy::panic-in-result-fn` implied by `-D warnings` -error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result` - --> $DIR/panic_in_result_fn.rs:11:5 - | -LL | / fn result_with_unimplemented() -> Result // should emit lint -LL | | { -LL | | unimplemented!(); -LL | | } - | |_____^ - | - = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing -note: return Err() instead of panicking - --> $DIR/panic_in_result_fn.rs:13:9 - | -LL | unimplemented!(); - | ^^^^^^^^^^^^^^^^ - -error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result` - --> $DIR/panic_in_result_fn.rs:16:5 - | -LL | / fn result_with_unreachable() -> Result // should emit lint -LL | | { -LL | | unreachable!(); -LL | | } - | |_____^ - | - = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing -note: return Err() instead of panicking - --> $DIR/panic_in_result_fn.rs:18:9 - | -LL | unreachable!(); - | ^^^^^^^^^^^^^^ - -error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result` - --> $DIR/panic_in_result_fn.rs:21:5 - | -LL | / fn result_with_todo() -> Result // should emit lint -LL | | { -LL | | todo!("Finish this"); -LL | | } - | |_____^ - | - = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing -note: return Err() instead of panicking - --> $DIR/panic_in_result_fn.rs:23:9 - | -LL | todo!("Finish this"); - | ^^^^^^^^^^^^^^^^^^^^ - -error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result` +error: used `panic!()` or assertion in a function that returns `Result` --> $DIR/panic_in_result_fn.rs:52:1 | LL | / fn function_result_with_panic() -> Result // should emit lint @@ -72,28 +24,12 @@ LL | | panic!("error"); LL | | } | |_^ | - = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing + = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking --> $DIR/panic_in_result_fn.rs:54:5 | LL | panic!("error"); | ^^^^^^^^^^^^^^^ -error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result` - --> $DIR/panic_in_result_fn.rs:67:1 - | -LL | / fn main() -> Result<(), String> { -LL | | todo!("finish main method"); -LL | | Ok(()) -LL | | } - | |_^ - | - = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing -note: return Err() instead of panicking - --> $DIR/panic_in_result_fn.rs:68:5 - | -LL | todo!("finish main method"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 6 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/panic_in_result_fn_assertions.stderr b/tests/ui/panic_in_result_fn_assertions.stderr index eb0aacbb6a44..0dd213a7eede 100644 --- a/tests/ui/panic_in_result_fn_assertions.stderr +++ b/tests/ui/panic_in_result_fn_assertions.stderr @@ -1,4 +1,4 @@ -error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result` +error: used `panic!()` or assertion in a function that returns `Result` --> $DIR/panic_in_result_fn_assertions.rs:7:5 | LL | / fn result_with_assert_with_message(x: i32) -> Result // should emit lint @@ -8,7 +8,7 @@ LL | | Ok(true) LL | | } | |_____^ | - = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing + = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking --> $DIR/panic_in_result_fn_assertions.rs:9:9 | @@ -16,7 +16,7 @@ LL | assert!(x == 5, "wrong argument"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: `-D clippy::panic-in-result-fn` implied by `-D warnings` -error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result` +error: used `panic!()` or assertion in a function that returns `Result` --> $DIR/panic_in_result_fn_assertions.rs:13:5 | LL | / fn result_with_assert_eq(x: i32) -> Result // should emit lint @@ -26,14 +26,14 @@ LL | | Ok(true) LL | | } | |_____^ | - = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing + = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking --> $DIR/panic_in_result_fn_assertions.rs:15:9 | LL | assert_eq!(x, 5); | ^^^^^^^^^^^^^^^^ -error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result` +error: used `panic!()` or assertion in a function that returns `Result` --> $DIR/panic_in_result_fn_assertions.rs:19:5 | LL | / fn result_with_assert_ne(x: i32) -> Result // should emit lint @@ -43,7 +43,7 @@ LL | | Ok(true) LL | | } | |_____^ | - = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing + = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking --> $DIR/panic_in_result_fn_assertions.rs:21:9 | diff --git a/tests/ui/partialeq_to_none.fixed b/tests/ui/partialeq_to_none.fixed index 4644ea8f51da..3e1a5a4a1544 100644 --- a/tests/ui/partialeq_to_none.fixed +++ b/tests/ui/partialeq_to_none.fixed @@ -1,5 +1,14 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::partialeq_to_none)] +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::eq_op, clippy::needless_if)] +======= +#![allow(clippy::eq_op)] +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= +#![allow(clippy::eq_op, clippy::needless_if)] +>>>>>>> 26f50395b (Add `needless_if` lint) struct Foobar; diff --git a/tests/ui/partialeq_to_none.rs b/tests/ui/partialeq_to_none.rs index 61011b3a8c55..006403f1f8b6 100644 --- a/tests/ui/partialeq_to_none.rs +++ b/tests/ui/partialeq_to_none.rs @@ -1,5 +1,14 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::partialeq_to_none)] +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::eq_op, clippy::needless_if)] +======= +#![allow(clippy::eq_op)] +>>>>>>> 58132cb3b (Improve `SpanlessEq`) +======= +#![allow(clippy::eq_op, clippy::needless_if)] +>>>>>>> 26f50395b (Add `needless_if` lint) struct Foobar; diff --git a/tests/ui/partialeq_to_none.stderr b/tests/ui/partialeq_to_none.stderr index d06ab7aee558..4f84862a22b8 100644 --- a/tests/ui/partialeq_to_none.stderr +++ b/tests/ui/partialeq_to_none.stderr @@ -1,5 +1,5 @@ error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:14:8 + --> $DIR/partialeq_to_none.rs:15:8 | LL | if f != None { "yay" } else { "nay" } | ^^^^^^^^^ help: use `Option::is_some()` instead: `f.is_some()` @@ -7,55 +7,55 @@ LL | if f != None { "yay" } else { "nay" } = note: `-D clippy::partialeq-to-none` implied by `-D warnings` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:44:13 + --> $DIR/partialeq_to_none.rs:45:13 | LL | let _ = x == None; | ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:45:13 + --> $DIR/partialeq_to_none.rs:46:13 | LL | let _ = x != None; | ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:46:13 + --> $DIR/partialeq_to_none.rs:47:13 | LL | let _ = None == x; | ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:47:13 + --> $DIR/partialeq_to_none.rs:48:13 | LL | let _ = None != x; | ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:49:8 + --> $DIR/partialeq_to_none.rs:50:8 | LL | if foobar() == None {} | ^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `foobar().is_none()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:51:8 + --> $DIR/partialeq_to_none.rs:52:8 | LL | if bar().ok() != None {} | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `bar().ok().is_some()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:53:13 + --> $DIR/partialeq_to_none.rs:54:13 | LL | let _ = Some(1 + 2) != None; | ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `Some(1 + 2).is_some()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:55:13 + --> $DIR/partialeq_to_none.rs:56:13 | LL | let _ = { Some(0) } == None; | ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `{ Some(0) }.is_none()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:57:13 + --> $DIR/partialeq_to_none.rs:58:13 | LL | let _ = { | _____________^ @@ -77,31 +77,31 @@ LL ~ }.is_some(); | error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:67:13 + --> $DIR/partialeq_to_none.rs:68:13 | LL | let _ = optref() == &&None; | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:68:13 + --> $DIR/partialeq_to_none.rs:69:13 | LL | let _ = &&None != optref(); | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:69:13 + --> $DIR/partialeq_to_none.rs:70:13 | LL | let _ = **optref() == None; | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:70:13 + --> $DIR/partialeq_to_none.rs:71:13 | LL | let _ = &None != *optref(); | ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()` error: binary comparison to literal `Option::None` - --> $DIR/partialeq_to_none.rs:73:13 + --> $DIR/partialeq_to_none.rs:74:13 | LL | let _ = None != *x; | ^^^^^^^^^^ help: use `Option::is_some()` instead: `(*x).is_some()` diff --git a/tests/ui/path_buf_push_overwrite.fixed b/tests/ui/path_buf_push_overwrite.fixed index ef8856830fc9..393fc6e1c693 100644 --- a/tests/ui/path_buf_push_overwrite.fixed +++ b/tests/ui/path_buf_push_overwrite.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix use std::path::PathBuf; #[warn(clippy::all, clippy::path_buf_push_overwrite)] diff --git a/tests/ui/path_buf_push_overwrite.rs b/tests/ui/path_buf_push_overwrite.rs index 6e2d483f4541..18de6e064126 100644 --- a/tests/ui/path_buf_push_overwrite.rs +++ b/tests/ui/path_buf_push_overwrite.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix use std::path::PathBuf; #[warn(clippy::all, clippy::path_buf_push_overwrite)] diff --git a/tests/ui/patterns.fixed b/tests/ui/patterns.fixed index cd69014326eb..5b2a32f201c6 100644 --- a/tests/ui/patterns.fixed +++ b/tests/ui/patterns.fixed @@ -1,8 +1,15 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::all)] #![allow(unused)] #![allow(clippy::uninlined_format_args)] +#[macro_use] +extern crate proc_macros; + fn main() { let v = Some(true); let s = [0, 1, 2, 3, 4]; @@ -34,4 +41,11 @@ fn main() { ref x => println!("vec: {:?}", x), ref y if y == &vec![0] => (), } + external! { + let v = Some(true); + match v { + Some(x) => (), + y @ _ => (), + } + } } diff --git a/tests/ui/patterns.rs b/tests/ui/patterns.rs index 9128da420c0d..5c2a21521323 100644 --- a/tests/ui/patterns.rs +++ b/tests/ui/patterns.rs @@ -1,8 +1,15 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::all)] #![allow(unused)] #![allow(clippy::uninlined_format_args)] +#[macro_use] +extern crate proc_macros; + fn main() { let v = Some(true); let s = [0, 1, 2, 3, 4]; @@ -34,4 +41,11 @@ fn main() { ref x @ _ => println!("vec: {:?}", x), ref y if y == &vec![0] => (), } + external! { + let v = Some(true); + match v { + Some(x) => (), + y @ _ => (), + } + } } diff --git a/tests/ui/patterns.stderr b/tests/ui/patterns.stderr index 2c46b4eb593e..276330d21c42 100644 --- a/tests/ui/patterns.stderr +++ b/tests/ui/patterns.stderr @@ -1,5 +1,5 @@ error: the `y @ _` pattern can be written as just `y` - --> $DIR/patterns.rs:11:9 + --> $DIR/patterns.rs:15:9 | LL | y @ _ => (), | ^^^^^ help: try: `y` @@ -7,13 +7,13 @@ LL | y @ _ => (), = note: `-D clippy::redundant-pattern` implied by `-D warnings` error: the `x @ _` pattern can be written as just `x` - --> $DIR/patterns.rs:26:9 + --> $DIR/patterns.rs:30:9 | LL | ref mut x @ _ => { | ^^^^^^^^^^^^^ help: try: `ref mut x` error: the `x @ _` pattern can be written as just `x` - --> $DIR/patterns.rs:34:9 + --> $DIR/patterns.rs:38:9 | LL | ref x @ _ => println!("vec: {:?}", x), | ^^^^^^^^^ help: try: `ref x` diff --git a/tests/ui/precedence.fixed b/tests/ui/precedence.fixed index 163bd044c178..af4d5636b616 100644 --- a/tests/ui/precedence.fixed +++ b/tests/ui/precedence.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::precedence)] #![allow(unused_must_use, clippy::no_effect, clippy::unnecessary_operation)] #![allow(clippy::identity_op)] diff --git a/tests/ui/precedence.rs b/tests/ui/precedence.rs index 8c849e3209b0..e23ae9127866 100644 --- a/tests/ui/precedence.rs +++ b/tests/ui/precedence.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::precedence)] #![allow(unused_must_use, clippy::no_effect, clippy::unnecessary_operation)] #![allow(clippy::identity_op)] diff --git a/tests/ui/print_literal.stderr b/tests/ui/print_literal.stderr index 6404dacdafa5..71c8d188f167 100644 --- a/tests/ui/print_literal.stderr +++ b/tests/ui/print_literal.stderr @@ -5,7 +5,7 @@ LL | print!("Hello {}", "world"); | ^^^^^^^ | = note: `-D clippy::print-literal` implied by `-D warnings` -help: try this +help: try | LL - print!("Hello {}", "world"); LL + print!("Hello world"); @@ -17,7 +17,7 @@ error: literal with an empty format string LL | println!("Hello {} {}", world, "world"); | ^^^^^^^ | -help: try this +help: try | LL - println!("Hello {} {}", world, "world"); LL + println!("Hello {} world", world); @@ -29,7 +29,7 @@ error: literal with an empty format string LL | println!("Hello {}", "world"); | ^^^^^^^ | -help: try this +help: try | LL - println!("Hello {}", "world"); LL + println!("Hello world"); @@ -41,7 +41,7 @@ error: literal with an empty format string LL | println!("{} {:.4}", "a literal", 5); | ^^^^^^^^^^^ | -help: try this +help: try | LL - println!("{} {:.4}", "a literal", 5); LL + println!("a literal {:.4}", 5); @@ -53,7 +53,7 @@ error: literal with an empty format string LL | println!("{0} {1}", "hello", "world"); | ^^^^^^^ | -help: try this +help: try | LL - println!("{0} {1}", "hello", "world"); LL + println!("hello {1}", "world"); @@ -65,7 +65,7 @@ error: literal with an empty format string LL | println!("{0} {1}", "hello", "world"); | ^^^^^^^ | -help: try this +help: try | LL - println!("{0} {1}", "hello", "world"); LL + println!("{0} world", "hello"); @@ -77,7 +77,7 @@ error: literal with an empty format string LL | println!("{1} {0}", "hello", "world"); | ^^^^^^^ | -help: try this +help: try | LL - println!("{1} {0}", "hello", "world"); LL + println!("world {0}", "hello"); @@ -89,7 +89,7 @@ error: literal with an empty format string LL | println!("{1} {0}", "hello", "world"); | ^^^^^^^ | -help: try this +help: try | LL - println!("{1} {0}", "hello", "world"); LL + println!("{1} hello", "world"); @@ -101,7 +101,7 @@ error: literal with an empty format string LL | println!("{foo} {bar}", foo = "hello", bar = "world"); | ^^^^^^^ | -help: try this +help: try | LL - println!("{foo} {bar}", foo = "hello", bar = "world"); LL + println!("hello {bar}", bar = "world"); @@ -113,7 +113,7 @@ error: literal with an empty format string LL | println!("{foo} {bar}", foo = "hello", bar = "world"); | ^^^^^^^ | -help: try this +help: try | LL - println!("{foo} {bar}", foo = "hello", bar = "world"); LL + println!("{foo} world", foo = "hello"); @@ -125,7 +125,7 @@ error: literal with an empty format string LL | println!("{bar} {foo}", foo = "hello", bar = "world"); | ^^^^^^^ | -help: try this +help: try | LL - println!("{bar} {foo}", foo = "hello", bar = "world"); LL + println!("world {foo}", foo = "hello"); @@ -137,7 +137,7 @@ error: literal with an empty format string LL | println!("{bar} {foo}", foo = "hello", bar = "world"); | ^^^^^^^ | -help: try this +help: try | LL - println!("{bar} {foo}", foo = "hello", bar = "world"); LL + println!("{bar} hello", bar = "world"); diff --git a/tests/ui/print_stdout_build_script.rs b/tests/ui/print_stdout_build_script.rs index 997ebef8a699..91448cb0faf8 100644 --- a/tests/ui/print_stdout_build_script.rs +++ b/tests/ui/print_stdout_build_script.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=build_script_build +//@compile-flags: --crate-name=build_script_build #![warn(clippy::print_stdout)] diff --git a/tests/ui/print_with_newline.fixed b/tests/ui/print_with_newline.fixed new file mode 100644 index 000000000000..6098dea39911 --- /dev/null +++ b/tests/ui/print_with_newline.fixed @@ -0,0 +1,58 @@ +// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934 +//@run-rustfix + +#![allow(clippy::print_literal)] +#![warn(clippy::print_with_newline)] + +fn main() { + println!("Hello"); + println!("Hello {}", "world"); + println!("Hello {} {}", "world", "#2"); + println!("{}", 1265); + println!(); + + // these are all fine + print!(""); + print!("Hello"); + println!("Hello"); + println!("Hello\n"); + println!("Hello {}\n", "world"); + print!("Issue\n{}", 1265); + print!("{}", 1265); + print!("\n{}", 1275); + print!("\n\n"); + print!("like eof\n\n"); + print!("Hello {} {}\n\n", "world", "#2"); + println!("\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126 + println!("\nbla\n\n"); // #3126 + + // Escaping + print!("\\n"); // #3514 + println!("\\"); // should fail + print!("\\\\n"); + + // Raw strings + print!(r"\n"); // #3778 + + // Literal newlines should also fail + println!( + + ); + println!( + + ); + + // Don't warn on CRLF (#4208) + print!("\r\n"); + print!("foo\r\n"); + println!("\\r"); // should fail + print!("foo\rbar\n"); + + // Ignore expanded format strings + macro_rules! newline { + () => { + "\n" + }; + } + print!(newline!()); +} diff --git a/tests/ui/print_with_newline.rs b/tests/ui/print_with_newline.rs index b8c29d207ada..d9c7acc27480 100644 --- a/tests/ui/print_with_newline.rs +++ b/tests/ui/print_with_newline.rs @@ -1,5 +1,5 @@ // FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934 -// // run-rustfix +// #![allow(clippy::print_literal)] #![warn(clippy::print_with_newline)] @@ -47,7 +47,7 @@ fn main() { // Don't warn on CRLF (#4208) print!("\r\n"); print!("foo\r\n"); - print!("\\r\n"); //~ ERROR + print!("\\r\n"); // should fail print!("foo\rbar\n"); // Ignore expanded format strings diff --git a/tests/ui/print_with_newline.stderr b/tests/ui/print_with_newline.stderr index b9f5675faec7..b97711e777dd 100644 --- a/tests/ui/print_with_newline.stderr +++ b/tests/ui/print_with_newline.stderr @@ -62,13 +62,13 @@ LL + println!(); error: using `print!()` with a format string that ends in a single newline --> $DIR/print_with_newline.rs:31:5 | -LL | print!("//n"); // should fail +LL | print!("///n"); // should fail | ^^^^^^^^^^^^^^ | help: use `println!` instead | -LL - print!("//n"); // should fail -LL + println!("/"); // should fail +LL - print!("///n"); // should fail +LL + println!("//"); // should fail | error: using `print!()` with a format string that ends in a single newline @@ -104,13 +104,13 @@ LL ~ error: using `print!()` with a format string that ends in a single newline --> $DIR/print_with_newline.rs:50:5 | -LL | print!("/r/n"); //~ ERROR +LL | print!("//r/n"); // should fail | ^^^^^^^^^^^^^^^ | help: use `println!` instead | -LL - print!("/r/n"); //~ ERROR -LL + println!("/r"); //~ ERROR +LL - print!("//r/n"); // should fail +LL + println!("//r"); // should fail | error: aborting due to 9 previous errors diff --git a/tests/ui/println_empty_string.fixed b/tests/ui/println_empty_string.fixed index 9760680927a6..abf951ae22d6 100644 --- a/tests/ui/println_empty_string.fixed +++ b/tests/ui/println_empty_string.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::match_single_binding)] fn main() { diff --git a/tests/ui/println_empty_string.rs b/tests/ui/println_empty_string.rs index 80fdb3e6e210..fd86e2543cc1 100644 --- a/tests/ui/println_empty_string.rs +++ b/tests/ui/println_empty_string.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::match_single_binding)] fn main() { diff --git a/tests/ui/proc_macro.rs b/tests/ui/proc_macro.rs index 59914b8b8f62..b77874034d0b 100644 --- a/tests/ui/proc_macro.rs +++ b/tests/ui/proc_macro.rs @@ -1,5 +1,4 @@ //! Check that we correctly lint procedural macros. -#![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/proc_macro.stderr b/tests/ui/proc_macro.stderr index c795f6ad0d25..d912b5027551 100644 --- a/tests/ui/proc_macro.stderr +++ b/tests/ui/proc_macro.stderr @@ -1,5 +1,5 @@ error: approximate value of `f{32, 64}::consts::PI` found - --> $DIR/proc_macro.rs:10:14 + --> $DIR/proc_macro.rs:9:14 | LL | let _x = 3.14; | ^^^^ diff --git a/tests/ui/ptr_arg.rs b/tests/ui/ptr_arg.rs index 5f54101ca15a..13e993d247b2 100644 --- a/tests/ui/ptr_arg.rs +++ b/tests/ui/ptr_arg.rs @@ -1,5 +1,11 @@ #![feature(lint_reasons)] -#![allow(unused, clippy::many_single_char_names, clippy::redundant_clone)] +#![allow( + unused, + clippy::many_single_char_names, + clippy::needless_lifetimes, + clippy::redundant_clone, + clippy::needless_pass_by_ref_mut +)] #![warn(clippy::ptr_arg)] use std::borrow::Cow; @@ -235,3 +241,29 @@ fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { takes_dyn(b); takes_dyn(c); } + +mod issue_9218 { + use std::borrow::Cow; + + fn cow_non_elided_lifetime<'a>(input: &Cow<'a, str>) -> &'a str { + todo!() + } + + // This one has an anonymous lifetime so it's not okay + fn cow_elided_lifetime<'a>(input: &'a Cow) -> &'a str { + todo!() + } + + // These two's return types don't use use 'a so it's not okay + fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str { + todo!() + } + fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str { + todo!() + } + + // Inferred to be `&'a str`, afaik. + fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str { + todo!() + } +} diff --git a/tests/ui/ptr_arg.stderr b/tests/ui/ptr_arg.stderr index 6b4de98ce88c..0e9dd760f453 100644 --- a/tests/ui/ptr_arg.stderr +++ b/tests/ui/ptr_arg.stderr @@ -1,5 +1,5 @@ error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:8:14 + --> $DIR/ptr_arg.rs:14:14 | LL | fn do_vec(x: &Vec) { | ^^^^^^^^^ help: change this to: `&[i64]` @@ -7,43 +7,43 @@ LL | fn do_vec(x: &Vec) { = note: `-D clippy::ptr-arg` implied by `-D warnings` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:12:18 + --> $DIR/ptr_arg.rs:18:18 | LL | fn do_vec_mut(x: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [i64]` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:16:14 + --> $DIR/ptr_arg.rs:22:14 | LL | fn do_str(x: &String) { | ^^^^^^^ help: change this to: `&str` error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:20:18 + --> $DIR/ptr_arg.rs:26:18 | LL | fn do_str_mut(x: &mut String) { | ^^^^^^^^^^^ help: change this to: `&mut str` error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:24:15 + --> $DIR/ptr_arg.rs:30:15 | LL | fn do_path(x: &PathBuf) { | ^^^^^^^^ help: change this to: `&Path` error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:28:19 + --> $DIR/ptr_arg.rs:34:19 | LL | fn do_path_mut(x: &mut PathBuf) { | ^^^^^^^^^^^^ help: change this to: `&mut Path` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:36:18 + --> $DIR/ptr_arg.rs:42:18 | LL | fn do_vec(x: &Vec); | ^^^^^^^^^ help: change this to: `&[i64]` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:49:14 + --> $DIR/ptr_arg.rs:55:14 | LL | fn cloned(x: &Vec) -> Vec { | ^^^^^^^^ @@ -60,7 +60,7 @@ LL ~ x.to_owned() | error: writing `&String` instead of `&str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:58:18 + --> $DIR/ptr_arg.rs:64:18 | LL | fn str_cloned(x: &String) -> String { | ^^^^^^^ @@ -76,7 +76,7 @@ LL ~ x.to_owned() | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:66:19 + --> $DIR/ptr_arg.rs:72:19 | LL | fn path_cloned(x: &PathBuf) -> PathBuf { | ^^^^^^^^ @@ -92,7 +92,7 @@ LL ~ x.to_path_buf() | error: writing `&String` instead of `&str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:74:44 + --> $DIR/ptr_arg.rs:80:44 | LL | fn false_positive_capacity(x: &Vec, y: &String) { | ^^^^^^^ @@ -106,19 +106,19 @@ LL ~ let c = y; | error: using a reference to `Cow` is not recommended - --> $DIR/ptr_arg.rs:88:25 + --> $DIR/ptr_arg.rs:94:25 | LL | fn test_cow_with_ref(c: &Cow<[i32]>) {} | ^^^^^^^^^^^ help: change this to: `&[i32]` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:117:66 + --> $DIR/ptr_arg.rs:123:66 | LL | fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec, _s: &String) {} | ^^^^^^^ help: change this to: `&str` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:146:21 + --> $DIR/ptr_arg.rs:152:21 | LL | fn foo_vec(vec: &Vec) { | ^^^^^^^^ @@ -131,7 +131,7 @@ LL ~ let _ = vec.to_owned().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:151:23 + --> $DIR/ptr_arg.rs:157:23 | LL | fn foo_path(path: &PathBuf) { | ^^^^^^^^ @@ -144,7 +144,7 @@ LL ~ let _ = path.to_path_buf().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:156:21 + --> $DIR/ptr_arg.rs:162:21 | LL | fn foo_str(str: &PathBuf) { | ^^^^^^^^ @@ -157,28 +157,46 @@ LL ~ let _ = str.to_path_buf().clone(); | error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:162:29 + --> $DIR/ptr_arg.rs:168:29 | LL | fn mut_vec_slice_methods(v: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:224:17 + --> $DIR/ptr_arg.rs:230:17 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]` error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:224:35 + --> $DIR/ptr_arg.rs:230:35 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^ help: change this to: `&mut str` error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do - --> $DIR/ptr_arg.rs:224:51 + --> $DIR/ptr_arg.rs:230:51 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^^ help: change this to: `&mut Path` -error: aborting due to 20 previous errors +error: using a reference to `Cow` is not recommended + --> $DIR/ptr_arg.rs:253:39 + | +LL | fn cow_elided_lifetime<'a>(input: &'a Cow) -> &'a str { + | ^^^^^^^^^^^^ help: change this to: `&str` + +error: using a reference to `Cow` is not recommended + --> $DIR/ptr_arg.rs:258:36 + | +LL | fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str { + | ^^^^^^^^^^^^^^^^ help: change this to: `&str` + +error: using a reference to `Cow` is not recommended + --> $DIR/ptr_arg.rs:261:40 + | +LL | fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str { + | ^^^^^^^^^^^^^^^^ help: change this to: `&str` + +error: aborting due to 23 previous errors diff --git a/tests/ui/ptr_as_ptr.fixed b/tests/ui/ptr_as_ptr.fixed index ee7b998a0b2f..0ee8fe9487e6 100644 --- a/tests/ui/ptr_as_ptr.fixed +++ b/tests/ui/ptr_as_ptr.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::ptr_as_ptr)] diff --git a/tests/ui/ptr_as_ptr.rs b/tests/ui/ptr_as_ptr.rs index c88329ce4ecc..b3d84eb6e891 100644 --- a/tests/ui/ptr_as_ptr.rs +++ b/tests/ui/ptr_as_ptr.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::ptr_as_ptr)] diff --git a/tests/ui/ptr_cast_constness.fixed b/tests/ui/ptr_cast_constness.fixed new file mode 100644 index 000000000000..93c823b66d6b --- /dev/null +++ b/tests/ui/ptr_cast_constness.fixed @@ -0,0 +1,138 @@ +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5bd97ac17 (Update tests) +//@aux-build:proc_macros.rs:proc-macro + +#![warn(clippy::ptr_cast_constness)] +#![allow(clippy::transmute_ptr_to_ref, clippy::unnecessary_cast, unused)] +======= +//@aux-build:proc_macros.rs + +#![warn(clippy::ptr_cast_constness)] +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> 8c191add8 (the implementation!!) +======= +#![allow(clippy::transmute_ptr_to_ref, unused)] +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) +======= +#![allow(clippy::transmute_ptr_to_ref, clippy::unnecessary_cast, unused)] +>>>>>>> cd1d7a3c6 (weird) + +extern crate proc_macros; +use proc_macros::{external, inline_macros}; + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) +unsafe fn ptr_to_ref(p: *const T, om: *mut U) { + let _: &mut T = std::mem::transmute(p.cast_mut()); + let _ = &mut *p.cast_mut(); + let _: &T = &*(om as *const T); +} + +<<<<<<< HEAD +======= +>>>>>>> 8c191add8 (the implementation!!) +======= +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) +#[inline_macros] +fn main() { + let ptr: *const u32 = &42_u32; + let mut_ptr: *mut u32 = &mut 42_u32; + +<<<<<<< HEAD +<<<<<<< HEAD + let _ = ptr as *const u32; + let _ = mut_ptr as *mut u32; +======= + let _ = ptr as *const i32; + let _ = mut_ptr as *mut i32; +>>>>>>> 8c191add8 (the implementation!!) +======= + let _ = ptr as *const u32; + let _ = mut_ptr as *mut u32; +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) + + // Make sure the lint can handle the difference in their operator precedences. + unsafe { + let ptr_ptr: *const *const u32 = &ptr; + let _ = (*ptr_ptr).cast_mut(); + } + + let _ = ptr.cast_mut(); + let _ = mut_ptr.cast_const(); + + // Lint this, since pointer::cast_mut and pointer::cast_const have ?Sized + let ptr_of_array: *const [u32; 4] = &[1, 2, 3, 4]; + let _ = ptr_of_array as *const [u32]; + let _ = ptr_of_array as *const dyn std::fmt::Debug; + + // Make sure the lint is triggered inside a macro +<<<<<<< HEAD +<<<<<<< HEAD + let _ = inline!($ptr as *const u32); + + // Do not lint inside macros from external crates + let _ = external!($ptr as *const u32); +} + +#[clippy::msrv = "1.64"] +fn _msrv_1_64() { +======= + let _ = inline!($ptr as *const i32); +======= + let _ = inline!($ptr as *const u32); +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) + + // Do not lint inside macros from external crates + let _ = external!($ptr as *const u32); +} + +#[clippy::msrv = "1.64"] +<<<<<<< HEAD +fn _msrv_1_37() { +>>>>>>> 8c191add8 (the implementation!!) +======= +fn _msrv_1_64() { +>>>>>>> 4ff1cd365 (add description and rename msrv tests) + let ptr: *const u32 = &42_u32; + let mut_ptr: *mut u32 = &mut 42_u32; + + // `pointer::cast_const` and `pointer::cast_mut` were stabilized in 1.65. Do not lint this +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) + let _ = ptr as *mut u32; + let _ = mut_ptr as *const u32; +} + +#[clippy::msrv = "1.65"] +fn _msrv_1_65() { +======= + let _ = ptr.cast_mut(); + let _ = mut_ptr.cast_const(); +======= + let _ = ptr as *mut i32; + let _ = mut_ptr as *const i32; +>>>>>>> c5a914b18 (check msrv) +} + +#[clippy::msrv = "1.65"] +<<<<<<< HEAD +fn _msrv_1_38() { +>>>>>>> 8c191add8 (the implementation!!) +======= +fn _msrv_1_65() { +>>>>>>> 4ff1cd365 (add description and rename msrv tests) + let ptr: *const u32 = &42_u32; + let mut_ptr: *mut u32 = &mut 42_u32; + + let _ = ptr.cast_mut(); + let _ = mut_ptr.cast_const(); +} diff --git a/tests/ui/ptr_cast_constness.rs b/tests/ui/ptr_cast_constness.rs new file mode 100644 index 000000000000..7eb43be2b0b8 --- /dev/null +++ b/tests/ui/ptr_cast_constness.rs @@ -0,0 +1,157 @@ +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 5bd97ac17 (Update tests) +//@aux-build:proc_macros.rs:proc-macro + +#![warn(clippy::ptr_cast_constness)] +#![allow(clippy::transmute_ptr_to_ref, clippy::unnecessary_cast, unused)] +======= +//@aux-build:proc_macros.rs + +#![warn(clippy::ptr_cast_constness)] +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> 8c191add8 (the implementation!!) +======= +#![allow(clippy::transmute_ptr_to_ref, unused)] +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) +======= +#![allow(clippy::transmute_ptr_to_ref, clippy::unnecessary_cast, unused)] +>>>>>>> cd1d7a3c6 (weird) + +extern crate proc_macros; +use proc_macros::{external, inline_macros}; + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) +unsafe fn ptr_to_ref(p: *const T, om: *mut U) { + let _: &mut T = std::mem::transmute(p as *mut T); + let _ = &mut *(p as *mut T); + let _: &T = &*(om as *const T); +} + +<<<<<<< HEAD +======= +>>>>>>> 8c191add8 (the implementation!!) +======= +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) +#[inline_macros] +fn main() { + let ptr: *const u32 = &42_u32; + let mut_ptr: *mut u32 = &mut 42_u32; + +<<<<<<< HEAD +<<<<<<< HEAD + let _ = ptr as *const u32; + let _ = mut_ptr as *mut u32; +======= + let _ = ptr as *const i32; + let _ = mut_ptr as *mut i32; +>>>>>>> 8c191add8 (the implementation!!) +======= + let _ = ptr as *const u32; + let _ = mut_ptr as *mut u32; +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) + + // Make sure the lint can handle the difference in their operator precedences. + unsafe { + let ptr_ptr: *const *const u32 = &ptr; +<<<<<<< HEAD +<<<<<<< HEAD + let _ = *ptr_ptr as *mut u32; + } + + let _ = ptr as *mut u32; + let _ = mut_ptr as *const u32; +======= + let _ = *ptr_ptr as *mut i32; + } + + let _ = ptr as *mut i32; + let _ = mut_ptr as *const i32; +>>>>>>> 8c191add8 (the implementation!!) +======= + let _ = *ptr_ptr as *mut u32; + } + + let _ = ptr as *mut u32; + let _ = mut_ptr as *const u32; +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) + + // Lint this, since pointer::cast_mut and pointer::cast_const have ?Sized + let ptr_of_array: *const [u32; 4] = &[1, 2, 3, 4]; + let _ = ptr_of_array as *const [u32]; + let _ = ptr_of_array as *const dyn std::fmt::Debug; + + // Make sure the lint is triggered inside a macro +<<<<<<< HEAD +<<<<<<< HEAD + let _ = inline!($ptr as *const u32); + + // Do not lint inside macros from external crates + let _ = external!($ptr as *const u32); +} + +#[clippy::msrv = "1.64"] +fn _msrv_1_64() { +======= + let _ = inline!($ptr as *const i32); +======= + let _ = inline!($ptr as *const u32); +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) + + // Do not lint inside macros from external crates + let _ = external!($ptr as *const u32); +} + +#[clippy::msrv = "1.64"] +<<<<<<< HEAD +fn _msrv_1_37() { +>>>>>>> 8c191add8 (the implementation!!) +======= +fn _msrv_1_64() { +>>>>>>> 4ff1cd365 (add description and rename msrv tests) + let ptr: *const u32 = &42_u32; + let mut_ptr: *mut u32 = &mut 42_u32; + + // `pointer::cast_const` and `pointer::cast_mut` were stabilized in 1.65. Do not lint this +<<<<<<< HEAD +<<<<<<< HEAD + let _ = ptr as *mut u32; + let _ = mut_ptr as *const u32; +} + +#[clippy::msrv = "1.65"] +fn _msrv_1_65() { + let ptr: *const u32 = &42_u32; + let mut_ptr: *mut u32 = &mut 42_u32; + + let _ = ptr as *mut u32; + let _ = mut_ptr as *const u32; +======= + let _ = ptr as *mut i32; + let _ = mut_ptr as *const i32; +======= + let _ = ptr as *mut u32; + let _ = mut_ptr as *const u32; +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) +} + +#[clippy::msrv = "1.65"] +fn _msrv_1_65() { + let ptr: *const u32 = &42_u32; + let mut_ptr: *mut u32 = &mut 42_u32; + +<<<<<<< HEAD + let _ = ptr as *mut i32; + let _ = mut_ptr as *const i32; +>>>>>>> 8c191add8 (the implementation!!) +======= + let _ = ptr as *mut u32; + let _ = mut_ptr as *const u32; +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) +} diff --git a/tests/ui/ptr_cast_constness.stderr b/tests/ui/ptr_cast_constness.stderr new file mode 100644 index 000000000000..01eb0eefcf7c --- /dev/null +++ b/tests/ui/ptr_cast_constness.stderr @@ -0,0 +1,100 @@ +<<<<<<< HEAD +<<<<<<< HEAD +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:11:41 + | +LL | let _: &mut T = std::mem::transmute(p as *mut T); + | ^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `p.cast_mut()` + | + = note: `-D clippy::ptr-cast-constness` implied by `-D warnings` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:12:19 + | +LL | let _ = &mut *(p as *mut T); + | ^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `p.cast_mut()` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:27:17 + | +LL | let _ = *ptr_ptr as *mut u32; + | ^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `(*ptr_ptr).cast_mut()` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:30:13 + | +LL | let _ = ptr as *mut u32; + | ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:31:13 + | +LL | let _ = mut_ptr as *const u32; + | ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:60:13 + | +LL | let _ = ptr as *mut u32; + | ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:61:13 + | +LL | let _ = mut_ptr as *const u32; +======= +error: `as` casting between raw pointers while changing its constness + --> $DIR/ptr_cast_constness.rs:20:17 +======= +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:11:41 +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) + | +LL | let _: &mut T = std::mem::transmute(p as *mut T); + | ^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `p.cast_mut()` + | + = note: `-D clippy::ptr-cast-constness` implied by `-D warnings` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:12:19 + | +LL | let _ = &mut *(p as *mut T); + | ^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `p.cast_mut()` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:27:17 + | +LL | let _ = *ptr_ptr as *mut u32; + | ^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `(*ptr_ptr).cast_mut()` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:30:13 + | +LL | let _ = ptr as *mut u32; + | ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:31:13 + | +LL | let _ = mut_ptr as *const u32; + | ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:60:13 + | +LL | let _ = ptr as *mut u32; + | ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()` + +error: `as` casting between raw pointers while changing only its constness + --> $DIR/ptr_cast_constness.rs:61:13 + | +<<<<<<< HEAD +LL | let _ = mut_ptr as *const i32; +>>>>>>> 8c191add8 (the implementation!!) +======= +LL | let _ = mut_ptr as *const u32; +>>>>>>> ad7c44b3e (only lint when `cast_from` and `cast_to`'s ty are the same) + | ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()` + +error: aborting due to 7 previous errors + diff --git a/tests/ui/ptr_eq.fixed b/tests/ui/ptr_eq.fixed index 209081e6e801..d5fa273d41f0 100644 --- a/tests/ui/ptr_eq.fixed +++ b/tests/ui/ptr_eq.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::ptr_eq)] macro_rules! mac { diff --git a/tests/ui/ptr_eq.rs b/tests/ui/ptr_eq.rs index 69162870807a..e033366a4aab 100644 --- a/tests/ui/ptr_eq.rs +++ b/tests/ui/ptr_eq.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::ptr_eq)] macro_rules! mac { diff --git a/tests/ui/ptr_offset_with_cast.fixed b/tests/ui/ptr_offset_with_cast.fixed index c57e2990fb95..cc3313b93005 100644 --- a/tests/ui/ptr_offset_with_cast.fixed +++ b/tests/ui/ptr_offset_with_cast.fixed @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(clippy::unnecessary_cast, clippy::useless_vec)] +======= #![allow(clippy::unnecessary_cast)] +>>>>>>> e4f5d83fa (Fixed formatting.) fn main() { let vec = vec![b'a', b'b', b'c']; diff --git a/tests/ui/ptr_offset_with_cast.rs b/tests/ui/ptr_offset_with_cast.rs index 3de7997acddd..54944342e26e 100644 --- a/tests/ui/ptr_offset_with_cast.rs +++ b/tests/ui/ptr_offset_with_cast.rs @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(clippy::unnecessary_cast, clippy::useless_vec)] +======= #![allow(clippy::unnecessary_cast)] +>>>>>>> e4f5d83fa (Fixed formatting.) fn main() { let vec = vec![b'a', b'b', b'c']; diff --git a/tests/ui/pub_with_shorthand.fixed b/tests/ui/pub_with_shorthand.fixed new file mode 100644 index 000000000000..22d36cc0df75 --- /dev/null +++ b/tests/ui/pub_with_shorthand.fixed @@ -0,0 +1,46 @@ +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> 8296a338d (new lints for visibility) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) +#![feature(custom_inner_attributes)] +#![allow(clippy::needless_pub_self, unused)] +#![warn(clippy::pub_with_shorthand)] +#![no_main] +#![rustfmt::skip] // rustfmt will remove `in`, understandable + // but very annoying for our purposes! + +#[macro_use] +extern crate proc_macros; + +pub(in self) fn a() {} +pub(in self) fn b() {} + +pub fn c() {} +mod a { + pub(in super) fn d() {} + pub(in super) fn e() {} + pub(in self) fn f() {} + pub(in crate) fn k() {} + pub(in crate) fn m() {} + mod b { + pub(in crate::a) fn l() {} + } +} + +external! { + pub(self) fn g() {} + pub(in self) fn h() {} +} +with_span! { + span + pub(self) fn i() {} + pub(in self) fn j() {} +} + +// not really anything more to test. just a really simple lint overall diff --git a/tests/ui/pub_with_shorthand.rs b/tests/ui/pub_with_shorthand.rs new file mode 100644 index 000000000000..84591c8bbbf3 --- /dev/null +++ b/tests/ui/pub_with_shorthand.rs @@ -0,0 +1,46 @@ +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> 8296a338d (new lints for visibility) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) +#![feature(custom_inner_attributes)] +#![allow(clippy::needless_pub_self, unused)] +#![warn(clippy::pub_with_shorthand)] +#![no_main] +#![rustfmt::skip] // rustfmt will remove `in`, understandable + // but very annoying for our purposes! + +#[macro_use] +extern crate proc_macros; + +pub(self) fn a() {} +pub(in self) fn b() {} + +pub fn c() {} +mod a { + pub(in super) fn d() {} + pub(super) fn e() {} + pub(self) fn f() {} + pub(crate) fn k() {} + pub(in crate) fn m() {} + mod b { + pub(in crate::a) fn l() {} + } +} + +external! { + pub(self) fn g() {} + pub(in self) fn h() {} +} +with_span! { + span + pub(self) fn i() {} + pub(in self) fn j() {} +} + +// not really anything more to test. just a really simple lint overall diff --git a/tests/ui/pub_with_shorthand.stderr b/tests/ui/pub_with_shorthand.stderr new file mode 100644 index 000000000000..323b5a23b247 --- /dev/null +++ b/tests/ui/pub_with_shorthand.stderr @@ -0,0 +1,28 @@ +error: usage of `pub` without `in` + --> $DIR/pub_with_shorthand.rs:13:1 + | +LL | pub(self) fn a() {} + | ^^^^^^^^^ help: add it: `pub(in self)` + | + = note: `-D clippy::pub-with-shorthand` implied by `-D warnings` + +error: usage of `pub` without `in` + --> $DIR/pub_with_shorthand.rs:19:5 + | +LL | pub(super) fn e() {} + | ^^^^^^^^^^ help: add it: `pub(in super)` + +error: usage of `pub` without `in` + --> $DIR/pub_with_shorthand.rs:20:5 + | +LL | pub(self) fn f() {} + | ^^^^^^^^^ help: add it: `pub(in self)` + +error: usage of `pub` without `in` + --> $DIR/pub_with_shorthand.rs:21:5 + | +LL | pub(crate) fn k() {} + | ^^^^^^^^^^ help: add it: `pub(in crate)` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/pub_without_shorthand.fixed b/tests/ui/pub_without_shorthand.fixed new file mode 100644 index 000000000000..d08fb4eb7877 --- /dev/null +++ b/tests/ui/pub_without_shorthand.fixed @@ -0,0 +1,46 @@ +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> 8296a338d (new lints for visibility) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) +#![feature(custom_inner_attributes)] +#![allow(clippy::needless_pub_self, unused)] +#![warn(clippy::pub_without_shorthand)] +#![no_main] +#![rustfmt::skip] // rustfmt will remove `in`, understandable + // but very annoying for our purposes! + +#[macro_use] +extern crate proc_macros; + +pub(self) fn a() {} +pub(self) fn b() {} + +pub fn c() {} +mod a { + pub(super) fn d() {} + pub(super) fn e() {} + pub(self) fn f() {} + pub(crate) fn k() {} + pub(crate) fn m() {} + mod b { + pub(in crate::a) fn l() {} + } +} + +external! { + pub(self) fn g() {} + pub(in self) fn h() {} +} +with_span! { + span + pub(self) fn i() {} + pub(in self) fn j() {} +} + +// not really anything more to test. just a really simple lint overall diff --git a/tests/ui/pub_without_shorthand.rs b/tests/ui/pub_without_shorthand.rs new file mode 100644 index 000000000000..8207a815c839 --- /dev/null +++ b/tests/ui/pub_without_shorthand.rs @@ -0,0 +1,46 @@ +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> 8296a338d (new lints for visibility) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 46aa8abf0 (Change category and update to `ui_test`) +#![feature(custom_inner_attributes)] +#![allow(clippy::needless_pub_self, unused)] +#![warn(clippy::pub_without_shorthand)] +#![no_main] +#![rustfmt::skip] // rustfmt will remove `in`, understandable + // but very annoying for our purposes! + +#[macro_use] +extern crate proc_macros; + +pub(self) fn a() {} +pub(in self) fn b() {} + +pub fn c() {} +mod a { + pub(in super) fn d() {} + pub(super) fn e() {} + pub(self) fn f() {} + pub(crate) fn k() {} + pub(in crate) fn m() {} + mod b { + pub(in crate::a) fn l() {} + } +} + +external! { + pub(self) fn g() {} + pub(in self) fn h() {} +} +with_span! { + span + pub(self) fn i() {} + pub(in self) fn j() {} +} + +// not really anything more to test. just a really simple lint overall diff --git a/tests/ui/pub_without_shorthand.stderr b/tests/ui/pub_without_shorthand.stderr new file mode 100644 index 000000000000..a18c9bf89344 --- /dev/null +++ b/tests/ui/pub_without_shorthand.stderr @@ -0,0 +1,22 @@ +error: usage of `pub` with `in` + --> $DIR/pub_without_shorthand.rs:14:1 + | +LL | pub(in self) fn b() {} + | ^^^^^^^^^^^^ help: remove it: `pub(self)` + | + = note: `-D clippy::pub-without-shorthand` implied by `-D warnings` + +error: usage of `pub` with `in` + --> $DIR/pub_without_shorthand.rs:18:5 + | +LL | pub(in super) fn d() {} + | ^^^^^^^^^^^^^ help: remove it: `pub(super)` + +error: usage of `pub` with `in` + --> $DIR/pub_without_shorthand.rs:22:5 + | +LL | pub(in crate) fn m() {} + | ^^^^^^^^^^^^^ help: remove it: `pub(crate)` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/question_mark.fixed b/tests/ui/question_mark.fixed index 5c49d46da726..93ee3fad2212 100644 --- a/tests/ui/question_mark.fixed +++ b/tests/ui/question_mark.fixed @@ -1,4 +1,8 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![feature(try_blocks)] +======= +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(unreachable_code)] #![allow(dead_code)] #![allow(clippy::unnecessary_wraps)] @@ -227,6 +231,36 @@ fn pattern() -> Result<(), PatternedError> { fn main() {} +// `?` is not the same as `return None;` if inside of a try block +fn issue8628(a: Option) -> Option { + let b: Option = try { + if a.is_none() { + return None; + } + 32 + }; + b.or(Some(128)) +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 70610c001 (lint in nested bodies if `try` is in outer body) +fn issue6828_nested_body() -> Option { + try { + fn f2(a: Option) -> Option { + a?; + Some(32) + } + 123 + } +} + +<<<<<<< HEAD +======= +>>>>>>> 716305d4b ([`question_mark`]: don't lint inside of `try` block) +======= +>>>>>>> 70610c001 (lint in nested bodies if `try` is in outer body) // should not lint, `?` operator not available in const context const fn issue9175(option: Option<()>) -> Option<()> { if option.is_none() { diff --git a/tests/ui/question_mark.rs b/tests/ui/question_mark.rs index d057df6a9b35..3322bc2f3989 100644 --- a/tests/ui/question_mark.rs +++ b/tests/ui/question_mark.rs @@ -1,4 +1,8 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![feature(try_blocks)] +======= +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(unreachable_code)] #![allow(dead_code)] #![allow(clippy::unnecessary_wraps)] @@ -263,6 +267,40 @@ fn pattern() -> Result<(), PatternedError> { fn main() {} +// `?` is not the same as `return None;` if inside of a try block +fn issue8628(a: Option) -> Option { + let b: Option = try { + if a.is_none() { + return None; + } + 32 + }; + b.or(Some(128)) +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 70610c001 (lint in nested bodies if `try` is in outer body) +fn issue6828_nested_body() -> Option { + try { + fn f2(a: Option) -> Option { + if a.is_none() { + return None; + // do lint here, the outer `try` is not relevant here + // https://github.com/rust-lang/rust-clippy/pull/11001#issuecomment-1610636867 + } + Some(32) + } + 123 + } +} + +<<<<<<< HEAD +======= +>>>>>>> 716305d4b ([`question_mark`]: don't lint inside of `try` block) +======= +>>>>>>> 70610c001 (lint in nested bodies if `try` is in outer body) // should not lint, `?` operator not available in const context const fn issue9175(option: Option<()>) -> Option<()> { if option.is_none() { diff --git a/tests/ui/question_mark.stderr b/tests/ui/question_mark.stderr index 23172d7e535d..2cfd75863081 100644 --- a/tests/ui/question_mark.stderr +++ b/tests/ui/question_mark.stderr @@ -1,5 +1,5 @@ error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:7:5 + --> $DIR/question_mark.rs:8:5 | LL | / if a.is_none() { LL | | return None; @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::question-mark` implied by `-D warnings` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:52:9 + --> $DIR/question_mark.rs:53:9 | LL | / if (self.opt).is_none() { LL | | return None; @@ -17,7 +17,7 @@ LL | | } | |_________^ help: replace it with: `(self.opt)?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:56:9 + --> $DIR/question_mark.rs:57:9 | LL | / if self.opt.is_none() { LL | | return None @@ -25,7 +25,7 @@ LL | | } | |_________^ help: replace it with: `self.opt?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:60:17 + --> $DIR/question_mark.rs:61:17 | LL | let _ = if self.opt.is_none() { | _________________^ @@ -36,7 +36,7 @@ LL | | }; | |_________^ help: replace it with: `Some(self.opt?)` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:66:17 + --> $DIR/question_mark.rs:67:17 | LL | let _ = if let Some(x) = self.opt { | _________________^ @@ -47,7 +47,7 @@ LL | | }; | |_________^ help: replace it with: `self.opt?` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:83:9 + --> $DIR/question_mark.rs:84:9 | LL | / if self.opt.is_none() { LL | | return None; @@ -55,7 +55,7 @@ LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:91:9 + --> $DIR/question_mark.rs:92:9 | LL | / if self.opt.is_none() { LL | | return None; @@ -63,7 +63,7 @@ LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:99:9 + --> $DIR/question_mark.rs:100:9 | LL | / if self.opt.is_none() { LL | | return None; @@ -71,7 +71,7 @@ LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:106:26 + --> $DIR/question_mark.rs:107:26 | LL | let v: &Vec<_> = if let Some(ref v) = self.opt { | __________________________^ @@ -82,7 +82,7 @@ LL | | }; | |_________^ help: replace it with: `self.opt.as_ref()?` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:116:17 + --> $DIR/question_mark.rs:117:17 | LL | let v = if let Some(v) = self.opt { | _________________^ @@ -93,7 +93,7 @@ LL | | }; | |_________^ help: replace it with: `self.opt?` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:131:5 + --> $DIR/question_mark.rs:132:5 | LL | / if f().is_none() { LL | | return None; @@ -101,13 +101,13 @@ LL | | } | |_____^ help: replace it with: `f()?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:143:13 + --> $DIR/question_mark.rs:144:13 | LL | let _ = if let Ok(x) = x { x } else { return x }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x?` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:145:5 + --> $DIR/question_mark.rs:146:5 | LL | / if x.is_err() { LL | | return x; @@ -115,7 +115,7 @@ LL | | } | |_____^ help: replace it with: `x?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:196:5 + --> $DIR/question_mark.rs:197:5 | LL | / if let Err(err) = func_returning_result() { LL | | return Err(err); @@ -123,12 +123,22 @@ LL | | } | |_____^ help: replace it with: `func_returning_result()?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:203:5 + --> $DIR/question_mark.rs:204:5 | LL | / if let Err(err) = func_returning_result() { LL | | return Err(err); LL | | } | |_____^ help: replace it with: `func_returning_result()?;` -error: aborting due to 15 previous errors +error: this block may be rewritten with the `?` operator + --> $DIR/question_mark.rs:281:13 + | +LL | / if a.is_none() { +LL | | return None; +LL | | // do lint here, the outer `try` is not relevant here +LL | | // https://github.com/rust-lang/rust-clippy/pull/11001#issuecomment-1610636867 +LL | | } + | |_____________^ help: replace it with: `a?;` + +error: aborting due to 16 previous errors diff --git a/tests/ui/range.rs b/tests/ui/range.rs index 628282509c1a..46edf0921bf2 100644 --- a/tests/ui/range.rs +++ b/tests/ui/range.rs @@ -1,3 +1,4 @@ +#![allow(clippy::useless_vec)] #[warn(clippy::range_zip_with_len)] fn main() { let v1 = vec![1, 2, 3]; diff --git a/tests/ui/range.stderr b/tests/ui/range.stderr index dcb5061371f8..ac83b67fde3a 100644 --- a/tests/ui/range.stderr +++ b/tests/ui/range.stderr @@ -1,5 +1,5 @@ error: it is more idiomatic to use `v1.iter().enumerate()` - --> $DIR/range.rs:5:14 + --> $DIR/range.rs:6:14 | LL | let _x = v1.iter().zip(0..v1.len()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/range_contains.fixed b/tests/ui/range_contains.fixed index 4923731fe45e..0a92ee7c8dd3 100644 --- a/tests/ui/range_contains.fixed +++ b/tests/ui/range_contains.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_range_contains)] #![allow(unused)] diff --git a/tests/ui/range_contains.rs b/tests/ui/range_contains.rs index d623ccb5da63..7a83be609571 100644 --- a/tests/ui/range_contains.rs +++ b/tests/ui/range_contains.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_range_contains)] #![allow(unused)] diff --git a/tests/ui/range_plus_minus_one.fixed b/tests/ui/range_plus_minus_one.fixed index a16a3e54d45e..79c133cb5e32 100644 --- a/tests/ui/range_plus_minus_one.fixed +++ b/tests/ui/range_plus_minus_one.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_parens)] #![allow(clippy::iter_with_drain)] diff --git a/tests/ui/range_plus_minus_one.rs b/tests/ui/range_plus_minus_one.rs index bd6cb4d21be5..689a6b7a17ce 100644 --- a/tests/ui/range_plus_minus_one.rs +++ b/tests/ui/range_plus_minus_one.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_parens)] #![allow(clippy::iter_with_drain)] diff --git a/tests/ui/rc_buffer.fixed b/tests/ui/rc_buffer.fixed index 8910c01b1fcf..4cba292c1b73 100644 --- a/tests/ui/rc_buffer.fixed +++ b/tests/ui/rc_buffer.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::rc_buffer)] #![allow(dead_code, unused_imports)] diff --git a/tests/ui/rc_buffer.rs b/tests/ui/rc_buffer.rs index 1e63a43262ec..d8a9aa2786d4 100644 --- a/tests/ui/rc_buffer.rs +++ b/tests/ui/rc_buffer.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::rc_buffer)] #![allow(dead_code, unused_imports)] diff --git a/tests/ui/rc_buffer_arc.fixed b/tests/ui/rc_buffer_arc.fixed index 13dd6f5fcd18..ac51ac9e4675 100644 --- a/tests/ui/rc_buffer_arc.fixed +++ b/tests/ui/rc_buffer_arc.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::rc_buffer)] #![allow(dead_code, unused_imports)] diff --git a/tests/ui/rc_buffer_arc.rs b/tests/ui/rc_buffer_arc.rs index 1a521bfeb7c8..21dc27bc5fa5 100644 --- a/tests/ui/rc_buffer_arc.rs +++ b/tests/ui/rc_buffer_arc.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::rc_buffer)] #![allow(dead_code, unused_imports)] diff --git a/tests/ui/rc_clone_in_vec_init/arc.rs b/tests/ui/rc_clone_in_vec_init/arc.rs index 384060e6eae5..53fcbf3c49b4 100644 --- a/tests/ui/rc_clone_in_vec_init/arc.rs +++ b/tests/ui/rc_clone_in_vec_init/arc.rs @@ -1,4 +1,5 @@ #![warn(clippy::rc_clone_in_vec_init)] +#![allow(clippy::useless_vec)] use std::sync::{Arc, Mutex}; fn main() {} diff --git a/tests/ui/rc_clone_in_vec_init/arc.stderr b/tests/ui/rc_clone_in_vec_init/arc.stderr index 7814f5b54036..a8fd28b84b3a 100644 --- a/tests/ui/rc_clone_in_vec_init/arc.stderr +++ b/tests/ui/rc_clone_in_vec_init/arc.stderr @@ -1,5 +1,5 @@ error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/arc.rs:7:13 + --> $DIR/arc.rs:8:13 | LL | let v = vec![Arc::new("x".to_string()); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/arc.rs:15:21 + --> $DIR/arc.rs:16:21 | LL | let v = vec![Arc::new("x".to_string()); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/arc.rs:21:13 + --> $DIR/arc.rs:22:13 | LL | let v = vec![ | _____________^ @@ -76,7 +76,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/arc.rs:30:14 + --> $DIR/arc.rs:31:14 | LL | let v1 = vec![ | ______________^ diff --git a/tests/ui/rc_clone_in_vec_init/rc.rs b/tests/ui/rc_clone_in_vec_init/rc.rs index 0394457fe170..88ea39bf9083 100644 --- a/tests/ui/rc_clone_in_vec_init/rc.rs +++ b/tests/ui/rc_clone_in_vec_init/rc.rs @@ -1,4 +1,5 @@ #![warn(clippy::rc_clone_in_vec_init)] +#![allow(clippy::useless_vec)] use std::rc::Rc; use std::sync::Mutex; diff --git a/tests/ui/rc_clone_in_vec_init/rc.stderr b/tests/ui/rc_clone_in_vec_init/rc.stderr index 80deb7cb9f24..eab464800ca9 100644 --- a/tests/ui/rc_clone_in_vec_init/rc.stderr +++ b/tests/ui/rc_clone_in_vec_init/rc.stderr @@ -1,5 +1,5 @@ error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/rc.rs:8:13 + --> $DIR/rc.rs:9:13 | LL | let v = vec![Rc::new("x".to_string()); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/rc.rs:16:21 + --> $DIR/rc.rs:17:21 | LL | let v = vec![Rc::new("x".to_string()); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/rc.rs:22:13 + --> $DIR/rc.rs:23:13 | LL | let v = vec![ | _____________^ @@ -76,7 +76,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/rc.rs:31:14 + --> $DIR/rc.rs:32:14 | LL | let v1 = vec![ | ______________^ diff --git a/tests/ui/rc_clone_in_vec_init/weak.rs b/tests/ui/rc_clone_in_vec_init/weak.rs index 693c9b553c56..03142165057d 100644 --- a/tests/ui/rc_clone_in_vec_init/weak.rs +++ b/tests/ui/rc_clone_in_vec_init/weak.rs @@ -1,4 +1,5 @@ #![warn(clippy::rc_clone_in_vec_init)] +#![allow(clippy::useless_vec)] use std::rc::{Rc, Weak as UnSyncWeak}; use std::sync::{Arc, Mutex, Weak as SyncWeak}; diff --git a/tests/ui/rc_clone_in_vec_init/weak.stderr b/tests/ui/rc_clone_in_vec_init/weak.stderr index 789e14a302f6..1f7a849b1808 100644 --- a/tests/ui/rc_clone_in_vec_init/weak.stderr +++ b/tests/ui/rc_clone_in_vec_init/weak.stderr @@ -1,5 +1,5 @@ error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/weak.rs:8:13 + --> $DIR/weak.rs:9:13 | LL | let v = vec![SyncWeak::::new(); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/weak.rs:9:14 + --> $DIR/weak.rs:10:14 | LL | let v2 = vec![UnSyncWeak::::new(); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/weak.rs:11:13 + --> $DIR/weak.rs:12:13 | LL | let v = vec![Rc::downgrade(&Rc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,7 +69,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/weak.rs:12:13 + --> $DIR/weak.rs:13:13 | LL | let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/weak.rs:20:21 + --> $DIR/weak.rs:21:21 | LL | let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -115,7 +115,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/weak.rs:21:22 + --> $DIR/weak.rs:22:22 | LL | let v2 = vec![Rc::downgrade(&Rc::new("x".to_string())); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -138,7 +138,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/weak.rs:27:13 + --> $DIR/weak.rs:28:13 | LL | let v = vec![ | _____________^ @@ -168,7 +168,7 @@ LL ~ }; | error: initializing a reference-counted pointer in `vec![elem; len]` - --> $DIR/weak.rs:36:14 + --> $DIR/weak.rs:37:14 | LL | let v1 = vec![ | ______________^ diff --git a/tests/ui/read_line_without_trim.fixed b/tests/ui/read_line_without_trim.fixed new file mode 100644 index 000000000000..cb6aab84e49a --- /dev/null +++ b/tests/ui/read_line_without_trim.fixed @@ -0,0 +1,36 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::read_line_without_trim)] + +fn main() { + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + input.pop(); + let _x: i32 = input.parse().unwrap(); // don't trigger here, newline character is popped + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + let _x: i32 = input.trim_end().parse().unwrap(); + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + let _x = input.trim_end().parse::().unwrap(); + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + let _x = input.trim_end().parse::().unwrap(); + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + let _x = input.trim_end().parse::().unwrap(); + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + let _x = input.trim_end().parse::().unwrap(); + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + // this is actually ok, so don't lint here + let _x = input.parse::().unwrap(); +} diff --git a/tests/ui/read_line_without_trim.rs b/tests/ui/read_line_without_trim.rs new file mode 100644 index 000000000000..bdc409a70106 --- /dev/null +++ b/tests/ui/read_line_without_trim.rs @@ -0,0 +1,36 @@ +//@run-rustfix + +#![allow(unused)] +#![warn(clippy::read_line_without_trim)] + +fn main() { + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + input.pop(); + let _x: i32 = input.parse().unwrap(); // don't trigger here, newline character is popped + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + let _x: i32 = input.parse().unwrap(); + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + let _x = input.parse::().unwrap(); + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + let _x = input.parse::().unwrap(); + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + let _x = input.parse::().unwrap(); + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + let _x = input.parse::().unwrap(); + + let mut input = String::new(); + std::io::stdin().read_line(&mut input).unwrap(); + // this is actually ok, so don't lint here + let _x = input.parse::().unwrap(); +} diff --git a/tests/ui/read_line_without_trim.stderr b/tests/ui/read_line_without_trim.stderr new file mode 100644 index 000000000000..f3d7b60425fb --- /dev/null +++ b/tests/ui/read_line_without_trim.stderr @@ -0,0 +1,73 @@ +error: calling `.parse()` without trimming the trailing newline character + --> $DIR/read_line_without_trim.rs:14:25 + | +LL | let _x: i32 = input.parse().unwrap(); + | ----- ^^^^^^^ + | | + | help: try: `input.trim_end()` + | +note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause `.parse()` to fail + --> $DIR/read_line_without_trim.rs:13:5 + | +LL | std::io::stdin().read_line(&mut input).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::read-line-without-trim` implied by `-D warnings` + +error: calling `.parse()` without trimming the trailing newline character + --> $DIR/read_line_without_trim.rs:18:20 + | +LL | let _x = input.parse::().unwrap(); + | ----- ^^^^^^^^^^^^^^ + | | + | help: try: `input.trim_end()` + | +note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause `.parse()` to fail + --> $DIR/read_line_without_trim.rs:17:5 + | +LL | std::io::stdin().read_line(&mut input).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: calling `.parse()` without trimming the trailing newline character + --> $DIR/read_line_without_trim.rs:22:20 + | +LL | let _x = input.parse::().unwrap(); + | ----- ^^^^^^^^^^^^^^ + | | + | help: try: `input.trim_end()` + | +note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause `.parse()` to fail + --> $DIR/read_line_without_trim.rs:21:5 + | +LL | std::io::stdin().read_line(&mut input).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: calling `.parse()` without trimming the trailing newline character + --> $DIR/read_line_without_trim.rs:26:20 + | +LL | let _x = input.parse::().unwrap(); + | ----- ^^^^^^^^^^^^^^ + | | + | help: try: `input.trim_end()` + | +note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause `.parse()` to fail + --> $DIR/read_line_without_trim.rs:25:5 + | +LL | std::io::stdin().read_line(&mut input).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: calling `.parse()` without trimming the trailing newline character + --> $DIR/read_line_without_trim.rs:30:20 + | +LL | let _x = input.parse::().unwrap(); + | ----- ^^^^^^^^^^^^^^^ + | | + | help: try: `input.trim_end()` + | +note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause `.parse()` to fail + --> $DIR/read_line_without_trim.rs:29:5 + | +LL | std::io::stdin().read_line(&mut input).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/read_zero_byte_vec.rs b/tests/ui/read_zero_byte_vec.rs index 30807e0f8b92..c6025ef1f4da 100644 --- a/tests/ui/read_zero_byte_vec.rs +++ b/tests/ui/read_zero_byte_vec.rs @@ -1,5 +1,5 @@ #![warn(clippy::read_zero_byte_vec)] -#![allow(clippy::unused_io_amount)] +#![allow(clippy::unused_io_amount, clippy::needless_pass_by_ref_mut)] use std::fs::File; use std::io; use std::io::prelude::*; diff --git a/tests/ui/redundant_allocation.rs b/tests/ui/redundant_allocation.rs index 574d34aed2d8..9eb58a3e53f6 100644 --- a/tests/ui/redundant_allocation.rs +++ b/tests/ui/redundant_allocation.rs @@ -8,8 +8,7 @@ pub struct SubT { } mod outer_box { - use crate::MyStruct; - use crate::SubT; + use crate::{MyStruct, SubT}; use std::boxed::Box; use std::rc::Rc; use std::sync::Arc; @@ -28,8 +27,7 @@ mod outer_box { } mod outer_rc { - use crate::MyStruct; - use crate::SubT; + use crate::{MyStruct, SubT}; use std::boxed::Box; use std::rc::Rc; use std::sync::Arc; @@ -48,8 +46,7 @@ mod outer_rc { } mod outer_arc { - use crate::MyStruct; - use crate::SubT; + use crate::{MyStruct, SubT}; use std::boxed::Box; use std::rc::Rc; use std::sync::Arc; diff --git a/tests/ui/redundant_allocation.stderr b/tests/ui/redundant_allocation.stderr index e0826fefa6cf..a9a1eed702b4 100644 --- a/tests/ui/redundant_allocation.stderr +++ b/tests/ui/redundant_allocation.stderr @@ -1,5 +1,5 @@ error: usage of `Box>` - --> $DIR/redundant_allocation.rs:17:30 + --> $DIR/redundant_allocation.rs:16:30 | LL | pub fn box_test6(foo: Box>) {} | ^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | pub fn box_test6(foo: Box>) {} = note: `-D clippy::redundant-allocation` implied by `-D warnings` error: usage of `Box>` - --> $DIR/redundant_allocation.rs:19:30 + --> $DIR/redundant_allocation.rs:18:30 | LL | pub fn box_test7(foo: Box>) {} | ^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | pub fn box_test7(foo: Box>) {} = help: consider using just `Box` or `Arc` error: usage of `Box>>` - --> $DIR/redundant_allocation.rs:21:27 + --> $DIR/redundant_allocation.rs:20:27 | LL | pub fn box_test8() -> Box>> { | ^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | pub fn box_test8() -> Box>> { = help: consider using just `Box>` or `Rc>` error: usage of `Box>` - --> $DIR/redundant_allocation.rs:25:30 + --> $DIR/redundant_allocation.rs:24:30 | LL | pub fn box_test9(foo: Box>) -> Box>> { | ^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | pub fn box_test9(foo: Box>) -> Box>> { = help: consider using just `Box` or `Arc` error: usage of `Box>>` - --> $DIR/redundant_allocation.rs:25:46 + --> $DIR/redundant_allocation.rs:24:46 | LL | pub fn box_test9(foo: Box>) -> Box>> { | ^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | pub fn box_test9(foo: Box>) -> Box>> { = help: consider using just `Box>` or `Arc>` error: usage of `Rc>` - --> $DIR/redundant_allocation.rs:37:24 + --> $DIR/redundant_allocation.rs:35:24 | LL | pub fn rc_test5(a: Rc>) {} | ^^^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | pub fn rc_test5(a: Rc>) {} = help: consider using just `Rc` or `Box` error: usage of `Rc>` - --> $DIR/redundant_allocation.rs:39:24 + --> $DIR/redundant_allocation.rs:37:24 | LL | pub fn rc_test7(a: Rc>) {} | ^^^^^^^^^^^^^ @@ -63,7 +63,7 @@ LL | pub fn rc_test7(a: Rc>) {} = help: consider using just `Rc` or `Arc` error: usage of `Rc>>` - --> $DIR/redundant_allocation.rs:41:26 + --> $DIR/redundant_allocation.rs:39:26 | LL | pub fn rc_test8() -> Rc>> { | ^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | pub fn rc_test8() -> Rc>> { = help: consider using just `Rc>` or `Box>` error: usage of `Rc>` - --> $DIR/redundant_allocation.rs:45:29 + --> $DIR/redundant_allocation.rs:43:29 | LL | pub fn rc_test9(foo: Rc>) -> Rc>> { | ^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | pub fn rc_test9(foo: Rc>) -> Rc>> { = help: consider using just `Rc` or `Arc` error: usage of `Rc>>` - --> $DIR/redundant_allocation.rs:45:44 + --> $DIR/redundant_allocation.rs:43:44 | LL | pub fn rc_test9(foo: Rc>) -> Rc>> { | ^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | pub fn rc_test9(foo: Rc>) -> Rc>> { = help: consider using just `Rc>` or `Arc>` error: usage of `Arc>` - --> $DIR/redundant_allocation.rs:57:25 + --> $DIR/redundant_allocation.rs:54:25 | LL | pub fn arc_test5(a: Arc>) {} | ^^^^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL | pub fn arc_test5(a: Arc>) {} = help: consider using just `Arc` or `Box` error: usage of `Arc>` - --> $DIR/redundant_allocation.rs:59:25 + --> $DIR/redundant_allocation.rs:56:25 | LL | pub fn arc_test6(a: Arc>) {} | ^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL | pub fn arc_test6(a: Arc>) {} = help: consider using just `Arc` or `Rc` error: usage of `Arc>>` - --> $DIR/redundant_allocation.rs:61:27 + --> $DIR/redundant_allocation.rs:58:27 | LL | pub fn arc_test8() -> Arc>> { | ^^^^^^^^^^^^^^^^^^^^^ @@ -117,7 +117,7 @@ LL | pub fn arc_test8() -> Arc>> { = help: consider using just `Arc>` or `Box>` error: usage of `Arc>` - --> $DIR/redundant_allocation.rs:65:30 + --> $DIR/redundant_allocation.rs:62:30 | LL | pub fn arc_test9(foo: Arc>) -> Arc>> { | ^^^^^^^^^^ @@ -126,7 +126,7 @@ LL | pub fn arc_test9(foo: Arc>) -> Arc>> { = help: consider using just `Arc` or `Rc` error: usage of `Arc>>` - --> $DIR/redundant_allocation.rs:65:45 + --> $DIR/redundant_allocation.rs:62:45 | LL | pub fn arc_test9(foo: Arc>) -> Arc>> { | ^^^^^^^^^^^^^^^^ @@ -135,7 +135,7 @@ LL | pub fn arc_test9(foo: Arc>) -> Arc>> { = help: consider using just `Arc>` or `Rc>` error: usage of `Rc>>` - --> $DIR/redundant_allocation.rs:87:27 + --> $DIR/redundant_allocation.rs:84:27 | LL | pub fn test_rc_box(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | pub fn test_rc_box(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> $DIR/redundant_allocation.rs:119:31 + --> $DIR/redundant_allocation.rs:116:31 | LL | pub fn test_rc_box_str(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^ @@ -153,7 +153,7 @@ LL | pub fn test_rc_box_str(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> $DIR/redundant_allocation.rs:120:33 + --> $DIR/redundant_allocation.rs:117:33 | LL | pub fn test_rc_box_slice(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -162,7 +162,7 @@ LL | pub fn test_rc_box_slice(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> $DIR/redundant_allocation.rs:121:32 + --> $DIR/redundant_allocation.rs:118:32 | LL | pub fn test_rc_box_path(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^ @@ -171,7 +171,7 @@ LL | pub fn test_rc_box_path(_: Rc>>) {} = help: consider using just `Rc>` or `Box>` error: usage of `Rc>>` - --> $DIR/redundant_allocation.rs:122:34 + --> $DIR/redundant_allocation.rs:119:34 | LL | pub fn test_rc_box_custom(_: Rc>>) {} | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/redundant_allocation_fixable.fixed b/tests/ui/redundant_allocation_fixable.fixed index 6db02718c70b..b97863daf226 100644 --- a/tests/ui/redundant_allocation_fixable.fixed +++ b/tests/ui/redundant_allocation_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![allow(clippy::boxed_local, clippy::needless_pass_by_value)] #![allow(clippy::disallowed_names, unused_variables, dead_code)] @@ -16,9 +16,7 @@ pub enum MyEnum { } mod outer_box { - use crate::MyEnum; - use crate::MyStruct; - use crate::SubT; + use crate::{MyEnum, MyStruct, SubT}; use std::boxed::Box; use std::rc::Rc; use std::sync::Arc; @@ -35,9 +33,7 @@ mod outer_box { } mod outer_rc { - use crate::MyEnum; - use crate::MyStruct; - use crate::SubT; + use crate::{MyEnum, MyStruct, SubT}; use std::boxed::Box; use std::rc::Rc; use std::sync::Arc; @@ -54,9 +50,7 @@ mod outer_rc { } mod outer_arc { - use crate::MyEnum; - use crate::MyStruct; - use crate::SubT; + use crate::{MyEnum, MyStruct, SubT}; use std::boxed::Box; use std::rc::Rc; use std::sync::Arc; diff --git a/tests/ui/redundant_allocation_fixable.rs b/tests/ui/redundant_allocation_fixable.rs index c15806f30c04..bffb6f8c0002 100644 --- a/tests/ui/redundant_allocation_fixable.rs +++ b/tests/ui/redundant_allocation_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![allow(clippy::boxed_local, clippy::needless_pass_by_value)] #![allow(clippy::disallowed_names, unused_variables, dead_code)] @@ -16,9 +16,7 @@ pub enum MyEnum { } mod outer_box { - use crate::MyEnum; - use crate::MyStruct; - use crate::SubT; + use crate::{MyEnum, MyStruct, SubT}; use std::boxed::Box; use std::rc::Rc; use std::sync::Arc; @@ -35,9 +33,7 @@ mod outer_box { } mod outer_rc { - use crate::MyEnum; - use crate::MyStruct; - use crate::SubT; + use crate::{MyEnum, MyStruct, SubT}; use std::boxed::Box; use std::rc::Rc; use std::sync::Arc; @@ -54,9 +50,7 @@ mod outer_rc { } mod outer_arc { - use crate::MyEnum; - use crate::MyStruct; - use crate::SubT; + use crate::{MyEnum, MyStruct, SubT}; use std::boxed::Box; use std::rc::Rc; use std::sync::Arc; diff --git a/tests/ui/redundant_allocation_fixable.stderr b/tests/ui/redundant_allocation_fixable.stderr index 8dd4a6a26874..524ca5bf467d 100644 --- a/tests/ui/redundant_allocation_fixable.stderr +++ b/tests/ui/redundant_allocation_fixable.stderr @@ -1,5 +1,5 @@ error: usage of `Box<&T>` - --> $DIR/redundant_allocation_fixable.rs:26:30 + --> $DIR/redundant_allocation_fixable.rs:24:30 | LL | pub fn box_test1(foo: Box<&T>) {} | ^^^^^^^ help: try: `&T` @@ -8,7 +8,7 @@ LL | pub fn box_test1(foo: Box<&T>) {} = note: `-D clippy::redundant-allocation` implied by `-D warnings` error: usage of `Box<&MyStruct>` - --> $DIR/redundant_allocation_fixable.rs:28:27 + --> $DIR/redundant_allocation_fixable.rs:26:27 | LL | pub fn box_test2(foo: Box<&MyStruct>) {} | ^^^^^^^^^^^^^^ help: try: `&MyStruct` @@ -16,7 +16,7 @@ LL | pub fn box_test2(foo: Box<&MyStruct>) {} = note: `&MyStruct` is already a pointer, `Box<&MyStruct>` allocates a pointer on the heap error: usage of `Box<&MyEnum>` - --> $DIR/redundant_allocation_fixable.rs:30:27 + --> $DIR/redundant_allocation_fixable.rs:28:27 | LL | pub fn box_test3(foo: Box<&MyEnum>) {} | ^^^^^^^^^^^^ help: try: `&MyEnum` @@ -24,7 +24,7 @@ LL | pub fn box_test3(foo: Box<&MyEnum>) {} = note: `&MyEnum` is already a pointer, `Box<&MyEnum>` allocates a pointer on the heap error: usage of `Box>` - --> $DIR/redundant_allocation_fixable.rs:34:30 + --> $DIR/redundant_allocation_fixable.rs:32:30 | LL | pub fn box_test5(foo: Box>) {} | ^^^^^^^^^^^ help: try: `Box` @@ -32,7 +32,7 @@ LL | pub fn box_test5(foo: Box>) {} = note: `Box` is already on the heap, `Box>` makes an extra allocation error: usage of `Rc<&T>` - --> $DIR/redundant_allocation_fixable.rs:45:29 + --> $DIR/redundant_allocation_fixable.rs:41:29 | LL | pub fn rc_test1(foo: Rc<&T>) {} | ^^^^^^ help: try: `&T` @@ -40,7 +40,7 @@ LL | pub fn rc_test1(foo: Rc<&T>) {} = note: `&T` is already a pointer, `Rc<&T>` allocates a pointer on the heap error: usage of `Rc<&MyStruct>` - --> $DIR/redundant_allocation_fixable.rs:47:26 + --> $DIR/redundant_allocation_fixable.rs:43:26 | LL | pub fn rc_test2(foo: Rc<&MyStruct>) {} | ^^^^^^^^^^^^^ help: try: `&MyStruct` @@ -48,7 +48,7 @@ LL | pub fn rc_test2(foo: Rc<&MyStruct>) {} = note: `&MyStruct` is already a pointer, `Rc<&MyStruct>` allocates a pointer on the heap error: usage of `Rc<&MyEnum>` - --> $DIR/redundant_allocation_fixable.rs:49:26 + --> $DIR/redundant_allocation_fixable.rs:45:26 | LL | pub fn rc_test3(foo: Rc<&MyEnum>) {} | ^^^^^^^^^^^ help: try: `&MyEnum` @@ -56,7 +56,7 @@ LL | pub fn rc_test3(foo: Rc<&MyEnum>) {} = note: `&MyEnum` is already a pointer, `Rc<&MyEnum>` allocates a pointer on the heap error: usage of `Rc>` - --> $DIR/redundant_allocation_fixable.rs:53:24 + --> $DIR/redundant_allocation_fixable.rs:49:24 | LL | pub fn rc_test6(a: Rc>) {} | ^^^^^^^^^^^^ help: try: `Rc` @@ -64,7 +64,7 @@ LL | pub fn rc_test6(a: Rc>) {} = note: `Rc` is already on the heap, `Rc>` makes an extra allocation error: usage of `Arc<&T>` - --> $DIR/redundant_allocation_fixable.rs:64:30 + --> $DIR/redundant_allocation_fixable.rs:58:30 | LL | pub fn arc_test1(foo: Arc<&T>) {} | ^^^^^^^ help: try: `&T` @@ -72,7 +72,7 @@ LL | pub fn arc_test1(foo: Arc<&T>) {} = note: `&T` is already a pointer, `Arc<&T>` allocates a pointer on the heap error: usage of `Arc<&MyStruct>` - --> $DIR/redundant_allocation_fixable.rs:66:27 + --> $DIR/redundant_allocation_fixable.rs:60:27 | LL | pub fn arc_test2(foo: Arc<&MyStruct>) {} | ^^^^^^^^^^^^^^ help: try: `&MyStruct` @@ -80,7 +80,7 @@ LL | pub fn arc_test2(foo: Arc<&MyStruct>) {} = note: `&MyStruct` is already a pointer, `Arc<&MyStruct>` allocates a pointer on the heap error: usage of `Arc<&MyEnum>` - --> $DIR/redundant_allocation_fixable.rs:68:27 + --> $DIR/redundant_allocation_fixable.rs:62:27 | LL | pub fn arc_test3(foo: Arc<&MyEnum>) {} | ^^^^^^^^^^^^ help: try: `&MyEnum` @@ -88,7 +88,7 @@ LL | pub fn arc_test3(foo: Arc<&MyEnum>) {} = note: `&MyEnum` is already a pointer, `Arc<&MyEnum>` allocates a pointer on the heap error: usage of `Arc>` - --> $DIR/redundant_allocation_fixable.rs:72:25 + --> $DIR/redundant_allocation_fixable.rs:66:25 | LL | pub fn arc_test7(a: Arc>) {} | ^^^^^^^^^^^^^^ help: try: `Arc` diff --git a/tests/ui/redundant_async_block.fixed b/tests/ui/redundant_async_block.fixed index ad96993c4a78..328958491eeb 100644 --- a/tests/ui/redundant_async_block.fixed +++ b/tests/ui/redundant_async_block.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::manual_async_fn)] #![warn(clippy::redundant_async_block)] diff --git a/tests/ui/redundant_async_block.rs b/tests/ui/redundant_async_block.rs index 7ae235583694..cd189b31555c 100644 --- a/tests/ui/redundant_async_block.rs +++ b/tests/ui/redundant_async_block.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::manual_async_fn)] #![warn(clippy::redundant_async_block)] diff --git a/tests/ui/redundant_at_rest_pattern.fixed b/tests/ui/redundant_at_rest_pattern.fixed new file mode 100644 index 000000000000..080cf13b5dac --- /dev/null +++ b/tests/ui/redundant_at_rest_pattern.fixed @@ -0,0 +1,27 @@ +//@run-rustfix +//@aux-build:proc_macros.rs:proc-macro +#![allow(irrefutable_let_patterns, unused)] +#![warn(clippy::redundant_at_rest_pattern)] + +#[macro_use] +extern crate proc_macros; + +fn main() { + if let a = [()] {} + if let ref a = [()] {} + if let mut a = [()] {} + if let ref mut a = [()] {} + let v = vec![()]; + if let a = &*v {} + let s = &[()]; + if let a = s {} + // Don't lint + if let [..] = &*v {} + if let [a] = &*v {} + if let [()] = &*v {} + if let [first, rest @ ..] = &*v {} + if let a = [()] {} + external! { + if let [a @ ..] = [()] {} + } +} diff --git a/tests/ui/redundant_at_rest_pattern.rs b/tests/ui/redundant_at_rest_pattern.rs new file mode 100644 index 000000000000..a8a802829564 --- /dev/null +++ b/tests/ui/redundant_at_rest_pattern.rs @@ -0,0 +1,27 @@ +//@run-rustfix +//@aux-build:proc_macros.rs:proc-macro +#![allow(irrefutable_let_patterns, unused)] +#![warn(clippy::redundant_at_rest_pattern)] + +#[macro_use] +extern crate proc_macros; + +fn main() { + if let [a @ ..] = [()] {} + if let [ref a @ ..] = [()] {} + if let [mut a @ ..] = [()] {} + if let [ref mut a @ ..] = [()] {} + let v = vec![()]; + if let [a @ ..] = &*v {} + let s = &[()]; + if let [a @ ..] = s {} + // Don't lint + if let [..] = &*v {} + if let [a] = &*v {} + if let [()] = &*v {} + if let [first, rest @ ..] = &*v {} + if let a = [()] {} + external! { + if let [a @ ..] = [()] {} + } +} diff --git a/tests/ui/redundant_at_rest_pattern.stderr b/tests/ui/redundant_at_rest_pattern.stderr new file mode 100644 index 000000000000..e2a4d9ffd57c --- /dev/null +++ b/tests/ui/redundant_at_rest_pattern.stderr @@ -0,0 +1,40 @@ +error: using a rest pattern to bind an entire slice to a local + --> $DIR/redundant_at_rest_pattern.rs:10:12 + | +LL | if let [a @ ..] = [()] {} + | ^^^^^^^^ help: this is better represented with just the binding: `a` + | + = note: `-D clippy::redundant-at-rest-pattern` implied by `-D warnings` + +error: using a rest pattern to bind an entire slice to a local + --> $DIR/redundant_at_rest_pattern.rs:11:12 + | +LL | if let [ref a @ ..] = [()] {} + | ^^^^^^^^^^^^ help: this is better represented with just the binding: `ref a` + +error: using a rest pattern to bind an entire slice to a local + --> $DIR/redundant_at_rest_pattern.rs:12:12 + | +LL | if let [mut a @ ..] = [()] {} + | ^^^^^^^^^^^^ help: this is better represented with just the binding: `mut a` + +error: using a rest pattern to bind an entire slice to a local + --> $DIR/redundant_at_rest_pattern.rs:13:12 + | +LL | if let [ref mut a @ ..] = [()] {} + | ^^^^^^^^^^^^^^^^ help: this is better represented with just the binding: `ref mut a` + +error: using a rest pattern to bind an entire slice to a local + --> $DIR/redundant_at_rest_pattern.rs:15:12 + | +LL | if let [a @ ..] = &*v {} + | ^^^^^^^^ help: this is better represented with just the binding: `a` + +error: using a rest pattern to bind an entire slice to a local + --> $DIR/redundant_at_rest_pattern.rs:17:12 + | +LL | if let [a @ ..] = s {} + | ^^^^^^^^ help: this is better represented with just the binding: `a` + +error: aborting due to 6 previous errors + diff --git a/tests/ui/redundant_clone.fixed b/tests/ui/redundant_clone.fixed index 00b427450935..18739902c8cd 100644 --- a/tests/ui/redundant_clone.fixed +++ b/tests/ui/redundant_clone.fixed @@ -1,7 +1,23 @@ -// run-rustfix +//@run-rustfix // rustfix-only-machine-applicable #![feature(lint_reasons)] +#![warn(clippy::redundant_clone)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> bfd5abad4 (Fix all the other tests) +#![allow( + clippy::drop_non_drop, + clippy::implicit_clone, + clippy::uninlined_format_args, + clippy::unnecessary_literal_unwrap +)] +<<<<<<< HEAD +======= #![allow(clippy::drop_non_drop, clippy::implicit_clone, clippy::uninlined_format_args)] +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= +>>>>>>> bfd5abad4 (Fix all the other tests) use std::ffi::OsString; use std::path::Path; diff --git a/tests/ui/redundant_clone.rs b/tests/ui/redundant_clone.rs index f899127db8d0..10d1214d1c0c 100644 --- a/tests/ui/redundant_clone.rs +++ b/tests/ui/redundant_clone.rs @@ -1,7 +1,23 @@ -// run-rustfix +//@run-rustfix // rustfix-only-machine-applicable #![feature(lint_reasons)] +#![warn(clippy::redundant_clone)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> bfd5abad4 (Fix all the other tests) +#![allow( + clippy::drop_non_drop, + clippy::implicit_clone, + clippy::uninlined_format_args, + clippy::unnecessary_literal_unwrap +)] +<<<<<<< HEAD +======= #![allow(clippy::drop_non_drop, clippy::implicit_clone, clippy::uninlined_format_args)] +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= +>>>>>>> bfd5abad4 (Fix all the other tests) use std::ffi::OsString; use std::path::Path; diff --git a/tests/ui/redundant_clone.stderr b/tests/ui/redundant_clone.stderr index 782590034d05..0763285302ef 100644 --- a/tests/ui/redundant_clone.stderr +++ b/tests/ui/redundant_clone.stderr @@ -1,180 +1,410 @@ error: redundant clone - --> $DIR/redundant_clone.rs:10:42 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:16:42 +======= + --> $DIR/redundant_clone.rs:11:42 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:16:42 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = ["lorem", "ipsum"].join(" ").to_string(); | ^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:10:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:16:14 +======= + --> $DIR/redundant_clone.rs:11:14 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:16:14 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = ["lorem", "ipsum"].join(" ").to_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: `-D clippy::redundant-clone` implied by `-D warnings` error: redundant clone - --> $DIR/redundant_clone.rs:13:15 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:19:15 +======= + --> $DIR/redundant_clone.rs:14:15 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:19:15 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = s.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:13:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:19:14 +======= + --> $DIR/redundant_clone.rs:14:14 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:19:14 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = s.clone(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:16:15 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:22:15 +======= + --> $DIR/redundant_clone.rs:17:15 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:22:15 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = s.to_string(); | ^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:16:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:22:14 +======= + --> $DIR/redundant_clone.rs:17:14 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:22:14 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = s.to_string(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:19:15 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:25:15 +======= + --> $DIR/redundant_clone.rs:20:15 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:25:15 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = s.to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:19:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:25:14 +======= + --> $DIR/redundant_clone.rs:20:14 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:25:14 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = s.to_owned(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:21:42 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:27:42 +======= + --> $DIR/redundant_clone.rs:22:42 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:27:42 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = Path::new("/a/b/").join("c").to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:21:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:27:14 +======= + --> $DIR/redundant_clone.rs:22:14 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:27:14 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = Path::new("/a/b/").join("c").to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:23:42 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:29:42 +======= + --> $DIR/redundant_clone.rs:24:42 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:29:42 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = Path::new("/a/b/").join("c").to_path_buf(); | ^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:23:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:29:14 +======= + --> $DIR/redundant_clone.rs:24:14 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:29:14 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = Path::new("/a/b/").join("c").to_path_buf(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:25:29 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:31:29 +======= + --> $DIR/redundant_clone.rs:26:29 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:31:29 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = OsString::new().to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:25:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:31:14 +======= + --> $DIR/redundant_clone.rs:26:14 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:31:14 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = OsString::new().to_owned(); | ^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:27:29 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:33:29 +======= + --> $DIR/redundant_clone.rs:28:29 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:33:29 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = OsString::new().to_os_string(); | ^^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:27:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:33:14 +======= + --> $DIR/redundant_clone.rs:28:14 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:33:14 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _s = OsString::new().to_os_string(); | ^^^^^^^^^^^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:38:19 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:44:19 +======= + --> $DIR/redundant_clone.rs:39:19 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:44:19 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _t = tup.0.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:38:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:44:14 +======= + --> $DIR/redundant_clone.rs:39:14 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:44:14 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _t = tup.0.clone(); | ^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:70:25 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:76:25 +======= + --> $DIR/redundant_clone.rs:71:25 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:76:25 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) } | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:70:24 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:76:24 +======= + --> $DIR/redundant_clone.rs:71:24 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:76:24 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) } | ^ error: redundant clone - --> $DIR/redundant_clone.rs:127:15 +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> bfd5abad4 (Fix all the other tests) + --> $DIR/redundant_clone.rs:133:15 | LL | let _s = s.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:127:14 + --> $DIR/redundant_clone.rs:133:14 +<<<<<<< HEAD | LL | let _s = s.clone(); | ^ error: redundant clone + --> $DIR/redundant_clone.rs:134:15 +======= --> $DIR/redundant_clone.rs:128:15 +>>>>>>> e29a68113 (Move redundant_clone to nursery) + | +LL | let _s = s.clone(); + | ^^^^^^^^ help: remove this + | +note: this value is dropped without further use + --> $DIR/redundant_clone.rs:134:14 +======= +>>>>>>> bfd5abad4 (Fix all the other tests) + | +LL | let _s = s.clone(); + | ^ + +error: redundant clone + --> $DIR/redundant_clone.rs:134:15 | LL | let _t = t.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:128:14 + --> $DIR/redundant_clone.rs:134:14 | LL | let _t = t.clone(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:138:19 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:144:19 +======= + --> $DIR/redundant_clone.rs:139:19 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:144:19 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _f = f.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:138:18 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:144:18 +======= + --> $DIR/redundant_clone.rs:139:18 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:144:18 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _f = f.clone(); | ^ error: redundant clone - --> $DIR/redundant_clone.rs:150:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:156:14 +======= + --> $DIR/redundant_clone.rs:151:14 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:156:14 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let y = x.clone().join("matthias"); | ^^^^^^^^ help: remove this | note: cloned value is neither consumed nor mutated - --> $DIR/redundant_clone.rs:150:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:156:13 +======= + --> $DIR/redundant_clone.rs:151:13 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:156:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let y = x.clone().join("matthias"); | ^^^^^^^^^ error: redundant clone - --> $DIR/redundant_clone.rs:204:11 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:210:11 +======= + --> $DIR/redundant_clone.rs:205:11 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:210:11 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | foo(&x.clone(), move || { | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> $DIR/redundant_clone.rs:204:10 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_clone.rs:210:10 +======= + --> $DIR/redundant_clone.rs:205:10 +>>>>>>> e29a68113 (Move redundant_clone to nursery) +======= + --> $DIR/redundant_clone.rs:210:10 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | foo(&x.clone(), move || { | ^ diff --git a/tests/ui/redundant_closure_call_fixable.fixed b/tests/ui/redundant_closure_call_fixable.fixed index b987fd2ce6f0..373ae121e979 100644 --- a/tests/ui/redundant_closure_call_fixable.fixed +++ b/tests/ui/redundant_closure_call_fixable.fixed @@ -1,8 +1,9 @@ -// run-rustfix +//@run-rustfix #![feature(async_closure)] #![warn(clippy::redundant_closure_call)] #![allow(clippy::redundant_async_block)] +#![allow(clippy::type_complexity)] #![allow(unused)] async fn something() -> u32 { @@ -38,4 +39,59 @@ fn main() { }; } m2!(); + issue9956(); +} + +fn issue9956() { + assert_eq!(43, 42); + + // ... and some more interesting cases I've found while implementing the fix + + // not actually immediately calling the closure: + let a = (|| 42); + dbg!(a()); + + // immediately calling it inside of a macro + dbg!(42); + + // immediately calling only one closure, so we can't remove the other ones + let a = (|| || 123); + dbg!(a()()); + + // nested async closures + let a = async { 1 }; + let h = async { a.await }; + + // macro expansion tests + macro_rules! echo { + ($e:expr) => { + $e + }; + } + let a = 1; + assert_eq!(a, 1); + let a = 123; + assert_eq!(a, 123); + + // chaining calls, but not closures + fn x() -> fn() -> fn() -> fn() -> i32 { + || || || 42 + } + let _ = x()()()(); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 3fe2478ec (don't unnecessarily walk more in visitor and add more tests) + + fn bar() -> fn(i32, i32) { + foo + } + fn foo(_: i32, _: i32) {} + bar()(42, 5); + foo(42, 5); +<<<<<<< HEAD +======= +>>>>>>> 7280ad9f7 ([`redundant_closure_call`]: handle nested closures) +======= +>>>>>>> 3fe2478ec (don't unnecessarily walk more in visitor and add more tests) } diff --git a/tests/ui/redundant_closure_call_fixable.rs b/tests/ui/redundant_closure_call_fixable.rs index 633a2979d5da..f32ada93399c 100644 --- a/tests/ui/redundant_closure_call_fixable.rs +++ b/tests/ui/redundant_closure_call_fixable.rs @@ -1,8 +1,9 @@ -// run-rustfix +//@run-rustfix #![feature(async_closure)] #![warn(clippy::redundant_closure_call)] #![allow(clippy::redundant_async_block)] +#![allow(clippy::type_complexity)] #![allow(unused)] async fn something() -> u32 { @@ -38,4 +39,59 @@ fn main() { }; } m2!(); + issue9956(); +} + +fn issue9956() { + assert_eq!((|| || 43)()(), 42); + + // ... and some more interesting cases I've found while implementing the fix + + // not actually immediately calling the closure: + let a = (|| 42); + dbg!(a()); + + // immediately calling it inside of a macro + dbg!((|| 42)()); + + // immediately calling only one closure, so we can't remove the other ones + let a = (|| || || 123)(); + dbg!(a()()); + + // nested async closures + let a = (|| || || || async || 1)()()()()(); + let h = async { a.await }; + + // macro expansion tests + macro_rules! echo { + ($e:expr) => { + $e + }; + } + let a = (|| echo!(|| echo!(|| 1)))()()(); + assert_eq!(a, 1); + let a = (|| echo!((|| 123)))()(); + assert_eq!(a, 123); + + // chaining calls, but not closures + fn x() -> fn() -> fn() -> fn() -> i32 { + || || || 42 + } + let _ = x()()()(); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 3fe2478ec (don't unnecessarily walk more in visitor and add more tests) + + fn bar() -> fn(i32, i32) { + foo + } + fn foo(_: i32, _: i32) {} + bar()((|| || 42)()(), 5); + foo((|| || 42)()(), 5); +<<<<<<< HEAD +======= +>>>>>>> 7280ad9f7 ([`redundant_closure_call`]: handle nested closures) +======= +>>>>>>> 3fe2478ec (don't unnecessarily walk more in visitor and add more tests) } diff --git a/tests/ui/redundant_closure_call_fixable.stderr b/tests/ui/redundant_closure_call_fixable.stderr index 8a1f0771659b..bbcdd3d9ade2 100644 --- a/tests/ui/redundant_closure_call_fixable.stderr +++ b/tests/ui/redundant_closure_call_fixable.stderr @@ -1,5 +1,5 @@ error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:17:13 + --> $DIR/redundant_closure_call_fixable.rs:18:13 | LL | let a = (|| 42)(); | ^^^^^^^^^ help: try doing something like: `42` @@ -7,7 +7,7 @@ LL | let a = (|| 42)(); = note: `-D clippy::redundant-closure-call` implied by `-D warnings` error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:18:13 + --> $DIR/redundant_closure_call_fixable.rs:19:13 | LL | let b = (async || { | _____________^ @@ -27,7 +27,7 @@ LL ~ }; | error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:23:13 + --> $DIR/redundant_closure_call_fixable.rs:24:13 | LL | let c = (|| { | _____________^ @@ -47,13 +47,13 @@ LL ~ }; | error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:28:13 + --> $DIR/redundant_closure_call_fixable.rs:29:13 | LL | let d = (async || something().await)(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }` error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:37:13 + --> $DIR/redundant_closure_call_fixable.rs:38:13 | LL | (|| m!())() | ^^^^^^^^^^^ help: try doing something like: `m!()` @@ -64,7 +64,7 @@ LL | m2!(); = note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info) error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:32:13 + --> $DIR/redundant_closure_call_fixable.rs:33:13 | LL | (|| 0)() | ^^^^^^^^ help: try doing something like: `0` @@ -74,5 +74,63 @@ LL | m2!(); | = note: this error originates in the macro `m` which comes from the expansion of the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 6 previous errors +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:46:16 + | +LL | assert_eq!((|| || 43)()(), 42); + | ^^^^^^^^^^^^^^ help: try doing something like: `43` + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:55:10 + | +LL | dbg!((|| 42)()); + | ^^^^^^^^^ help: try doing something like: `42` + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:58:13 + | +LL | let a = (|| || || 123)(); + | ^^^^^^^^^^^^^^^^ help: try doing something like: `(|| || 123)` + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:62:13 + | +LL | let a = (|| || || || async || 1)()()()()(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { 1 }` + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:71:13 + | +LL | let a = (|| echo!(|| echo!(|| 1)))()()(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `1` + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:73:13 + | +LL | let a = (|| echo!((|| 123)))()(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `123` + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 3fe2478ec (don't unnecessarily walk more in visitor and add more tests) +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:86:11 + | +LL | bar()((|| || 42)()(), 5); + | ^^^^^^^^^^^^^^ help: try doing something like: `42` + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:87:9 + | +LL | foo((|| || 42)()(), 5); + | ^^^^^^^^^^^^^^ help: try doing something like: `42` + +error: aborting due to 14 previous errors +<<<<<<< HEAD +======= +error: aborting due to 12 previous errors +>>>>>>> 7280ad9f7 ([`redundant_closure_call`]: handle nested closures) +======= +>>>>>>> 3fe2478ec (don't unnecessarily walk more in visitor and add more tests) diff --git a/tests/ui/redundant_field_names.fixed b/tests/ui/redundant_field_names.fixed index 276266a2dd80..d2a65399da65 100644 --- a/tests/ui/redundant_field_names.fixed +++ b/tests/ui/redundant_field_names.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::redundant_field_names)] #![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)] diff --git a/tests/ui/redundant_field_names.rs b/tests/ui/redundant_field_names.rs index f674141c138e..605ffd21e2f7 100644 --- a/tests/ui/redundant_field_names.rs +++ b/tests/ui/redundant_field_names.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::redundant_field_names)] #![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)] diff --git a/tests/ui/redundant_pattern_matching_drop_order.fixed b/tests/ui/redundant_pattern_matching_drop_order.fixed index ce3229f17591..301bb03e8ade 100644 --- a/tests/ui/redundant_pattern_matching_drop_order.fixed +++ b/tests/ui/redundant_pattern_matching_drop_order.fixed @@ -1,8 +1,23 @@ -// run-rustfix +//@run-rustfix // Issue #5746 #![warn(clippy::redundant_pattern_matching)] -#![allow(clippy::if_same_then_else, clippy::equatable_if_let)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 26f50395b (Add `needless_if` lint) +#![allow( + clippy::if_same_then_else, + clippy::equatable_if_let, + clippy::needless_if, + clippy::needless_else +)] +<<<<<<< HEAD +======= +#![allow(clippy::if_same_then_else, clippy::equatable_if_let, clippy::needless_else)] +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= +>>>>>>> 26f50395b (Add `needless_if` lint) use std::task::Poll::{Pending, Ready}; fn main() { diff --git a/tests/ui/redundant_pattern_matching_drop_order.rs b/tests/ui/redundant_pattern_matching_drop_order.rs index 29b8543cf473..1c46a0f1e136 100644 --- a/tests/ui/redundant_pattern_matching_drop_order.rs +++ b/tests/ui/redundant_pattern_matching_drop_order.rs @@ -1,8 +1,23 @@ -// run-rustfix +//@run-rustfix // Issue #5746 #![warn(clippy::redundant_pattern_matching)] -#![allow(clippy::if_same_then_else, clippy::equatable_if_let)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 26f50395b (Add `needless_if` lint) +#![allow( + clippy::if_same_then_else, + clippy::equatable_if_let, + clippy::needless_if, + clippy::needless_else +)] +<<<<<<< HEAD +======= +#![allow(clippy::if_same_then_else, clippy::equatable_if_let, clippy::needless_else)] +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= +>>>>>>> 26f50395b (Add `needless_if` lint) use std::task::Poll::{Pending, Ready}; fn main() { diff --git a/tests/ui/redundant_pattern_matching_drop_order.stderr b/tests/ui/redundant_pattern_matching_drop_order.stderr index 23f08103f358..28f33f0c95d7 100644 --- a/tests/ui/redundant_pattern_matching_drop_order.stderr +++ b/tests/ui/redundant_pattern_matching_drop_order.stderr @@ -1,171 +1,171 @@ error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_drop_order.rs:12:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:17:12 | LL | if let Ok(_) = m.lock() {} - | -------^^^^^----------- help: try this: `if m.lock().is_ok()` + | -------^^^^^----------- help: try: `if m.lock().is_ok()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_drop_order.rs:13:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:18:12 | LL | if let Err(_) = Err::<(), _>(m.lock().unwrap().0) {} - | -------^^^^^^------------------------------------ help: try this: `if Err::<(), _>(m.lock().unwrap().0).is_err()` + | -------^^^^^^------------------------------------ help: try: `if Err::<(), _>(m.lock().unwrap().0).is_err()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_drop_order.rs:16:16 + --> $DIR/redundant_pattern_matching_drop_order.rs:21:16 | LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {} - | -------^^^^^----------------------------------------- help: try this: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()` + | -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_drop_order.rs:18:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:23:12 | LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) { - | -------^^^^^----------------------------------------- help: try this: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()` + | -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_drop_order.rs:21:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:26:12 | LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {} - | -------^^^^^----------------------------------------- help: try this: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()` + | -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_drop_order.rs:22:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:27:12 | LL | if let Err(_) = Err::, _>(()) {} - | -------^^^^^^------------------------------------------ help: try this: `if Err::, _>(()).is_err()` + | -------^^^^^^------------------------------------------ help: try: `if Err::, _>(()).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_drop_order.rs:24:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:29:12 | LL | if let Ok(_) = Ok::<_, ()>(String::new()) {} - | -------^^^^^----------------------------- help: try this: `if Ok::<_, ()>(String::new()).is_ok()` + | -------^^^^^----------------------------- help: try: `if Ok::<_, ()>(String::new()).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_drop_order.rs:25:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:30:12 | LL | if let Err(_) = Err::<(), _>((String::new(), ())) {} - | -------^^^^^^------------------------------------ help: try this: `if Err::<(), _>((String::new(), ())).is_err()` + | -------^^^^^^------------------------------------ help: try: `if Err::<(), _>((String::new(), ())).is_err()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_drop_order.rs:28:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:33:12 | LL | if let Some(_) = Some(m.lock()) {} - | -------^^^^^^^----------------- help: try this: `if Some(m.lock()).is_some()` + | -------^^^^^^^----------------- help: try: `if Some(m.lock()).is_some()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_drop_order.rs:29:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:34:12 | LL | if let Some(_) = Some(m.lock().unwrap().0) {} - | -------^^^^^^^---------------------------- help: try this: `if Some(m.lock().unwrap().0).is_some()` + | -------^^^^^^^---------------------------- help: try: `if Some(m.lock().unwrap().0).is_some()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_drop_order.rs:32:16 + --> $DIR/redundant_pattern_matching_drop_order.rs:37:16 | LL | if let None = None::> {} - | -------^^^^------------------------------------ help: try this: `if None::>.is_none()` + | -------^^^^------------------------------------ help: try: `if None::>.is_none()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_drop_order.rs:34:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:39:12 | LL | if let None = None::> { - | -------^^^^------------------------------------ help: try this: `if None::>.is_none()` + | -------^^^^------------------------------------ help: try: `if None::>.is_none()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_drop_order.rs:38:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:43:12 | LL | if let None = None::> {} - | -------^^^^------------------------------------ help: try this: `if None::>.is_none()` + | -------^^^^------------------------------------ help: try: `if None::>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_drop_order.rs:40:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:45:12 | LL | if let Some(_) = Some(String::new()) {} - | -------^^^^^^^---------------------- help: try this: `if Some(String::new()).is_some()` + | -------^^^^^^^---------------------- help: try: `if Some(String::new()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_drop_order.rs:41:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:46:12 | LL | if let Some(_) = Some((String::new(), ())) {} - | -------^^^^^^^---------------------------- help: try this: `if Some((String::new(), ())).is_some()` + | -------^^^^^^^---------------------------- help: try: `if Some((String::new(), ())).is_some()` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_drop_order.rs:44:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:49:12 | LL | if let Ready(_) = Ready(m.lock()) {} - | -------^^^^^^^^------------------ help: try this: `if Ready(m.lock()).is_ready()` + | -------^^^^^^^^------------------ help: try: `if Ready(m.lock()).is_ready()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_drop_order.rs:45:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:50:12 | LL | if let Ready(_) = Ready(m.lock().unwrap().0) {} - | -------^^^^^^^^----------------------------- help: try this: `if Ready(m.lock().unwrap().0).is_ready()` + | -------^^^^^^^^----------------------------- help: try: `if Ready(m.lock().unwrap().0).is_ready()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_drop_order.rs:48:16 + --> $DIR/redundant_pattern_matching_drop_order.rs:53:16 | LL | if let Pending = Pending::> {} - | -------^^^^^^^--------------------------------------- help: try this: `if Pending::>.is_pending()` + | -------^^^^^^^--------------------------------------- help: try: `if Pending::>.is_pending()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_drop_order.rs:50:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:55:12 | LL | if let Pending = Pending::> { - | -------^^^^^^^--------------------------------------- help: try this: `if Pending::>.is_pending()` + | -------^^^^^^^--------------------------------------- help: try: `if Pending::>.is_pending()` | = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_drop_order.rs:54:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:59:12 | LL | if let Pending = Pending::> {} - | -------^^^^^^^--------------------------------------- help: try this: `if Pending::>.is_pending()` + | -------^^^^^^^--------------------------------------- help: try: `if Pending::>.is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_drop_order.rs:56:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:61:12 | LL | if let Ready(_) = Ready(String::new()) {} - | -------^^^^^^^^----------------------- help: try this: `if Ready(String::new()).is_ready()` + | -------^^^^^^^^----------------------- help: try: `if Ready(String::new()).is_ready()` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_drop_order.rs:57:12 + --> $DIR/redundant_pattern_matching_drop_order.rs:62:12 | LL | if let Ready(_) = Ready((String::new(), ())) {} - | -------^^^^^^^^----------------------------- help: try this: `if Ready((String::new(), ())).is_ready()` + | -------^^^^^^^^----------------------------- help: try: `if Ready((String::new(), ())).is_ready()` error: aborting due to 22 previous errors diff --git a/tests/ui/redundant_pattern_matching_ipaddr.fixed b/tests/ui/redundant_pattern_matching_ipaddr.fixed index 21bae909555c..02f197aa26a3 100644 --- a/tests/ui/redundant_pattern_matching_ipaddr.fixed +++ b/tests/ui/redundant_pattern_matching_ipaddr.fixed @@ -1,16 +1,15 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::redundant_pattern_matching)] #![allow(unused_must_use)] #![allow( clippy::match_like_matches_macro, clippy::needless_bool, + clippy::needless_if, clippy::uninlined_format_args )] -use std::net::{ - IpAddr::{self, V4, V6}, - Ipv4Addr, Ipv6Addr, -}; +use std::net::IpAddr::{self, V4, V6}; +use std::net::{Ipv4Addr, Ipv6Addr}; fn main() { let ipaddr: IpAddr = V4(Ipv4Addr::LOCALHOST); diff --git a/tests/ui/redundant_pattern_matching_ipaddr.rs b/tests/ui/redundant_pattern_matching_ipaddr.rs index 4dd9171677ec..5c1e1810f550 100644 --- a/tests/ui/redundant_pattern_matching_ipaddr.rs +++ b/tests/ui/redundant_pattern_matching_ipaddr.rs @@ -1,16 +1,15 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::redundant_pattern_matching)] #![allow(unused_must_use)] #![allow( clippy::match_like_matches_macro, clippy::needless_bool, + clippy::needless_if, clippy::uninlined_format_args )] -use std::net::{ - IpAddr::{self, V4, V6}, - Ipv4Addr, Ipv6Addr, -}; +use std::net::IpAddr::{self, V4, V6}; +use std::net::{Ipv4Addr, Ipv6Addr}; fn main() { let ipaddr: IpAddr = V4(Ipv4Addr::LOCALHOST); diff --git a/tests/ui/redundant_pattern_matching_ipaddr.stderr b/tests/ui/redundant_pattern_matching_ipaddr.stderr index 536b589de54c..bec8d30884d0 100644 --- a/tests/ui/redundant_pattern_matching_ipaddr.stderr +++ b/tests/ui/redundant_pattern_matching_ipaddr.stderr @@ -1,130 +1,130 @@ error: redundant pattern matching, consider using `is_ipv4()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:17:12 + --> $DIR/redundant_pattern_matching_ipaddr.rs:16:12 | LL | if let V4(_) = &ipaddr {} - | -------^^^^^---------- help: try this: `if ipaddr.is_ipv4()` + | -------^^^^^---------- help: try: `if ipaddr.is_ipv4()` | = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` error: redundant pattern matching, consider using `is_ipv4()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:19:12 + --> $DIR/redundant_pattern_matching_ipaddr.rs:18:12 | LL | if let V4(_) = V4(Ipv4Addr::LOCALHOST) {} - | -------^^^^^-------------------------- help: try this: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()` + | -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:21:12 + --> $DIR/redundant_pattern_matching_ipaddr.rs:20:12 | LL | if let V6(_) = V6(Ipv6Addr::LOCALHOST) {} - | -------^^^^^-------------------------- help: try this: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()` + | -------^^^^^-------------------------- help: try: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:23:15 + --> $DIR/redundant_pattern_matching_ipaddr.rs:22:15 | LL | while let V4(_) = V4(Ipv4Addr::LOCALHOST) {} - | ----------^^^^^-------------------------- help: try this: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()` + | ----------^^^^^-------------------------- help: try: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:25:15 + --> $DIR/redundant_pattern_matching_ipaddr.rs:24:15 | LL | while let V6(_) = V6(Ipv6Addr::LOCALHOST) {} - | ----------^^^^^-------------------------- help: try this: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()` + | ----------^^^^^-------------------------- help: try: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:35:5 + --> $DIR/redundant_pattern_matching_ipaddr.rs:34:5 | LL | / match V4(Ipv4Addr::LOCALHOST) { LL | | V4(_) => true, LL | | V6(_) => false, LL | | }; - | |_____^ help: try this: `V4(Ipv4Addr::LOCALHOST).is_ipv4()` + | |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:40:5 + --> $DIR/redundant_pattern_matching_ipaddr.rs:39:5 | LL | / match V4(Ipv4Addr::LOCALHOST) { LL | | V4(_) => false, LL | | V6(_) => true, LL | | }; - | |_____^ help: try this: `V4(Ipv4Addr::LOCALHOST).is_ipv6()` + | |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv6()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:45:5 + --> $DIR/redundant_pattern_matching_ipaddr.rs:44:5 | LL | / match V6(Ipv6Addr::LOCALHOST) { LL | | V4(_) => false, LL | | V6(_) => true, LL | | }; - | |_____^ help: try this: `V6(Ipv6Addr::LOCALHOST).is_ipv6()` + | |_____^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:50:5 + --> $DIR/redundant_pattern_matching_ipaddr.rs:49:5 | LL | / match V6(Ipv6Addr::LOCALHOST) { LL | | V4(_) => true, LL | | V6(_) => false, LL | | }; - | |_____^ help: try this: `V6(Ipv6Addr::LOCALHOST).is_ipv4()` + | |_____^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv4()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:55:20 + --> $DIR/redundant_pattern_matching_ipaddr.rs:54:20 | LL | let _ = if let V4(_) = V4(Ipv4Addr::LOCALHOST) { - | -------^^^^^-------------------------- help: try this: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()` + | -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv4()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:63:20 + --> $DIR/redundant_pattern_matching_ipaddr.rs:62:20 | LL | let _ = if let V4(_) = gen_ipaddr() { - | -------^^^^^--------------- help: try this: `if gen_ipaddr().is_ipv4()` + | -------^^^^^--------------- help: try: `if gen_ipaddr().is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:65:19 + --> $DIR/redundant_pattern_matching_ipaddr.rs:64:19 | LL | } else if let V6(_) = gen_ipaddr() { - | -------^^^^^--------------- help: try this: `if gen_ipaddr().is_ipv6()` + | -------^^^^^--------------- help: try: `if gen_ipaddr().is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:77:12 + --> $DIR/redundant_pattern_matching_ipaddr.rs:76:12 | LL | if let V4(_) = V4(Ipv4Addr::LOCALHOST) {} - | -------^^^^^-------------------------- help: try this: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()` + | -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:79:12 + --> $DIR/redundant_pattern_matching_ipaddr.rs:78:12 | LL | if let V6(_) = V6(Ipv6Addr::LOCALHOST) {} - | -------^^^^^-------------------------- help: try this: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()` + | -------^^^^^-------------------------- help: try: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:81:15 + --> $DIR/redundant_pattern_matching_ipaddr.rs:80:15 | LL | while let V4(_) = V4(Ipv4Addr::LOCALHOST) {} - | ----------^^^^^-------------------------- help: try this: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()` + | ----------^^^^^-------------------------- help: try: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:83:15 + --> $DIR/redundant_pattern_matching_ipaddr.rs:82:15 | LL | while let V6(_) = V6(Ipv6Addr::LOCALHOST) {} - | ----------^^^^^-------------------------- help: try this: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()` + | ----------^^^^^-------------------------- help: try: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: redundant pattern matching, consider using `is_ipv4()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:85:5 + --> $DIR/redundant_pattern_matching_ipaddr.rs:84:5 | LL | / match V4(Ipv4Addr::LOCALHOST) { LL | | V4(_) => true, LL | | V6(_) => false, LL | | }; - | |_____^ help: try this: `V4(Ipv4Addr::LOCALHOST).is_ipv4()` + | |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv4()` error: redundant pattern matching, consider using `is_ipv6()` - --> $DIR/redundant_pattern_matching_ipaddr.rs:90:5 + --> $DIR/redundant_pattern_matching_ipaddr.rs:89:5 | LL | / match V6(Ipv6Addr::LOCALHOST) { LL | | V4(_) => false, LL | | V6(_) => true, LL | | }; - | |_____^ help: try this: `V6(Ipv6Addr::LOCALHOST).is_ipv6()` + | |_____^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv6()` error: aborting due to 18 previous errors diff --git a/tests/ui/redundant_pattern_matching_option.fixed b/tests/ui/redundant_pattern_matching_option.fixed index a89845c1dd32..e2ba15c5b583 100644 --- a/tests/ui/redundant_pattern_matching_option.fixed +++ b/tests/ui/redundant_pattern_matching_option.fixed @@ -1,10 +1,11 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow( unused_must_use, clippy::needless_bool, + clippy::needless_if, clippy::match_like_matches_macro, clippy::equatable_if_let, clippy::if_same_then_else @@ -46,6 +47,15 @@ fn main() { let _ = if opt.is_some() { true } else { false }; issue6067(); + issue10726(); +<<<<<<< HEAD +<<<<<<< HEAD + issue10803(); +======= +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + issue10803(); +>>>>>>> 0b507c6f0 (redundant pattern matches! result) let _ = if gen_opt().is_some() { 1 @@ -54,6 +64,8 @@ fn main() { } else { 3 }; + + if gen_opt().is_some() {} } fn gen_opt() -> Option<()> { @@ -86,3 +98,68 @@ fn issue7921() { if (&None::<()>).is_none() {} if (&None::<()>).is_none() {} } + +fn issue10726() { +<<<<<<< HEAD +<<<<<<< HEAD + let x = Some(42); + + x.is_some(); + + x.is_none(); + + x.is_none(); +<<<<<<< HEAD + + x.is_some(); + + // Don't lint + match x { + Some(21) => true, + _ => false, + }; +} + +fn issue10803() { + let x = Some(42); + + let _ = x.is_some(); + + let _ = x.is_none(); + + // Don't lint + let _ = matches!(x, Some(16)); +<<<<<<< HEAD +======= + Some(42).is_some(); +======= + let x = Some(42); + let y = None::<()>; +>>>>>>> c53ceba56 (update tests) + + x.is_some(); + +<<<<<<< HEAD + None::<()>.is_some(); +<<<<<<< HEAD +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= +======= + x.is_none(); +>>>>>>> c53ceba56 (update tests) + + y.is_some(); +======= +>>>>>>> 79a8867ad (update test option) + + x.is_some(); + + // Don't lint + match x { + Some(21) => true, + _ => false, + }; +>>>>>>> 342ce3da0 (fix reviewer comments) +======= +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +} diff --git a/tests/ui/redundant_pattern_matching_option.rs b/tests/ui/redundant_pattern_matching_option.rs index d6f44403487e..e40ea95e486f 100644 --- a/tests/ui/redundant_pattern_matching_option.rs +++ b/tests/ui/redundant_pattern_matching_option.rs @@ -1,10 +1,11 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow( unused_must_use, clippy::needless_bool, + clippy::needless_if, clippy::match_like_matches_macro, clippy::equatable_if_let, clippy::if_same_then_else @@ -55,6 +56,15 @@ fn main() { let _ = if let Some(_) = opt { true } else { false }; issue6067(); + issue10726(); +<<<<<<< HEAD +<<<<<<< HEAD + issue10803(); +======= +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + issue10803(); +>>>>>>> 0b507c6f0 (redundant pattern matches! result) let _ = if let Some(_) = gen_opt() { 1 @@ -63,6 +73,8 @@ fn main() { } else { 3 }; + + if let Some(..) = gen_opt() {} } fn gen_opt() -> Option<()> { @@ -101,3 +113,134 @@ fn issue7921() { if let None = *(&None::<()>) {} if let None = *&None::<()> {} } + +fn issue10726() { +<<<<<<< HEAD +<<<<<<< HEAD + let x = Some(42); + + match x { +======= + match Some(42) { +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + let x = Some(42); + + match x { +>>>>>>> c53ceba56 (update tests) + Some(_) => true, + _ => false, + }; + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> c53ceba56 (update tests) + match x { + None => true, + _ => false, + }; + +<<<<<<< HEAD +<<<<<<< HEAD + match x { +======= + match Some(42) { +<<<<<<< HEAD +>>>>>>> afa2741e6 (redundant_pattern_matching) + Some(_) => false, + _ => true, + }; + +<<<<<<< HEAD + match x { +======= + match Some(42) { +======= +>>>>>>> 342ce3da0 (fix reviewer comments) + None => true, + _ => false, + }; + +<<<<<<< HEAD + match Some(42) { +>>>>>>> afa2741e6 (redundant_pattern_matching) + None => false, + _ => true, + }; + +<<<<<<< HEAD + // Don't lint + match x { + Some(21) => true, + _ => false, + }; +} + +fn issue10803() { + let x = Some(42); + + let _ = matches!(x, Some(_)); + + let _ = matches!(x, None); + + // Don't lint + let _ = matches!(x, Some(16)); +======= + match None::<()> { + Some(_) => false, + _ => true, + }; + + match None::<()> { + Some(_) => false, + _ => true, + }; + + match None::<()> { + None => true, + _ => false, + }; + + match None::<()> { + None => false, + _ => true, + }; +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + match None::<()> { +======= + match y { +>>>>>>> c53ceba56 (update tests) + Some(_) => true, + _ => false, +======= + match x { + Some(_) => false, + _ => true, +>>>>>>> 79a8867ad (update test option) + }; + + match x { + None => false, + _ => true, + }; + + // Don't lint + match x { + Some(21) => true, + _ => false, + }; +>>>>>>> 342ce3da0 (fix reviewer comments) +} + +fn issue10803() { + let x = Some(42); + + let _ = matches!(x, Some(_)); + + let _ = matches!(x, None); + + // Don't lint + let _ = matches!(x, Some(16)); +} diff --git a/tests/ui/redundant_pattern_matching_option.stderr b/tests/ui/redundant_pattern_matching_option.stderr index 27ff812ba45e..93f9de315812 100644 --- a/tests/ui/redundant_pattern_matching_option.stderr +++ b/tests/ui/redundant_pattern_matching_option.stderr @@ -1,146 +1,461 @@ error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:14:12 + --> $DIR/redundant_pattern_matching_option.rs:15:12 | LL | if let None = None::<()> {} - | -------^^^^------------- help: try this: `if None::<()>.is_none()` + | -------^^^^------------- help: try: `if None::<()>.is_none()` | = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:16:12 + --> $DIR/redundant_pattern_matching_option.rs:17:12 | LL | if let Some(_) = Some(42) {} - | -------^^^^^^^----------- help: try this: `if Some(42).is_some()` + | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:18:12 + --> $DIR/redundant_pattern_matching_option.rs:19:12 | LL | if let Some(_) = Some(42) { - | -------^^^^^^^----------- help: try this: `if Some(42).is_some()` + | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:24:15 + --> $DIR/redundant_pattern_matching_option.rs:25:15 | LL | while let Some(_) = Some(42) {} - | ----------^^^^^^^----------- help: try this: `while Some(42).is_some()` + | ----------^^^^^^^----------- help: try: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:26:15 + --> $DIR/redundant_pattern_matching_option.rs:27:15 | LL | while let None = Some(42) {} - | ----------^^^^----------- help: try this: `while Some(42).is_none()` + | ----------^^^^----------- help: try: `while Some(42).is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:28:15 + --> $DIR/redundant_pattern_matching_option.rs:29:15 | LL | while let None = None::<()> {} - | ----------^^^^------------- help: try this: `while None::<()>.is_none()` + | ----------^^^^------------- help: try: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:31:15 + --> $DIR/redundant_pattern_matching_option.rs:32:15 | LL | while let Some(_) = v.pop() { - | ----------^^^^^^^---------- help: try this: `while v.pop().is_some()` + | ----------^^^^^^^---------- help: try: `while v.pop().is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:39:5 + --> $DIR/redundant_pattern_matching_option.rs:40:5 | LL | / match Some(42) { LL | | Some(_) => true, LL | | None => false, LL | | }; - | |_____^ help: try this: `Some(42).is_some()` + | |_____^ help: try: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:44:5 + --> $DIR/redundant_pattern_matching_option.rs:45:5 | LL | / match None::<()> { LL | | Some(_) => false, LL | | None => true, LL | | }; - | |_____^ help: try this: `None::<()>.is_none()` + | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:49:13 + --> $DIR/redundant_pattern_matching_option.rs:50:13 | LL | let _ = match None::<()> { | _____________^ LL | | Some(_) => false, LL | | None => true, LL | | }; - | |_____^ help: try this: `None::<()>.is_none()` + | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:55:20 + --> $DIR/redundant_pattern_matching_option.rs:56:20 | LL | let _ = if let Some(_) = opt { true } else { false }; - | -------^^^^^^^------ help: try this: `if opt.is_some()` + | -------^^^^^^^------ help: try: `if opt.is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:59:20 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:62:20 +======= + --> $DIR/redundant_pattern_matching_option.rs:60:20 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_option.rs:61:20 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:62:20 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | let _ = if let Some(_) = gen_opt() { - | -------^^^^^^^------------ help: try this: `if gen_opt().is_some()` + | -------^^^^^^^------------ help: try: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:61:19 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:64:19 +======= + --> $DIR/redundant_pattern_matching_option.rs:62:19 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_option.rs:63:19 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:64:19 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | } else if let None = gen_opt() { - | -------^^^^------------ help: try this: `if gen_opt().is_none()` + | -------^^^^------------ help: try: `if gen_opt().is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:80:12 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:70:12 +======= + --> $DIR/redundant_pattern_matching_option.rs:68:12 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_option.rs:69:12 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:70:12 +>>>>>>> 26f50395b (Add `needless_if` lint) + | +LL | if let Some(..) = gen_opt() {} + | -------^^^^^^^^------------ help: try: `if gen_opt().is_some()` + +error: redundant pattern matching, consider using `is_some()` +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:85:12 +======= + --> $DIR/redundant_pattern_matching_option.rs:83:12 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_option.rs:84:12 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:85:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/redundant_pattern_matching_option.rs:67:12 + | +LL | if let Some(..) = gen_opt() {} + | -------^^^^^^^^------------ help: try this: `if gen_opt().is_some()` + +error: redundant pattern matching, consider using `is_some()` + --> $DIR/redundant_pattern_matching_option.rs:82:12 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | if let Some(_) = Some(42) {} - | -------^^^^^^^----------- help: try this: `if Some(42).is_some()` + | -------^^^^^^^----------- help: try: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:82:12 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:87:12 +======= + --> $DIR/redundant_pattern_matching_option.rs:85:12 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_option.rs:86:12 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:87:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/redundant_pattern_matching_option.rs:84:12 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | if let None = None::<()> {} - | -------^^^^------------- help: try this: `if None::<()>.is_none()` + | -------^^^^------------- help: try: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:84:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:89:15 +======= + --> $DIR/redundant_pattern_matching_option.rs:87:15 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_option.rs:88:15 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:89:15 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/redundant_pattern_matching_option.rs:86:15 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | while let Some(_) = Some(42) {} - | ----------^^^^^^^----------- help: try this: `while Some(42).is_some()` + | ----------^^^^^^^----------- help: try: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:86:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:91:15 +======= + --> $DIR/redundant_pattern_matching_option.rs:89:15 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_option.rs:90:15 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:91:15 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/redundant_pattern_matching_option.rs:88:15 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | while let None = None::<()> {} - | ----------^^^^------------- help: try this: `while None::<()>.is_none()` + | ----------^^^^------------- help: try: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_option.rs:88:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:93:5 +======= + --> $DIR/redundant_pattern_matching_option.rs:91:5 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_option.rs:92:5 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:93:5 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/redundant_pattern_matching_option.rs:90:5 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | / match Some(42) { LL | | Some(_) => true, LL | | None => false, LL | | }; - | |_____^ help: try this: `Some(42).is_some()` + | |_____^ help: try: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:93:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:98:5 +======= + --> $DIR/redundant_pattern_matching_option.rs:96:5 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_option.rs:97:5 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:98:5 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/redundant_pattern_matching_option.rs:95:5 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | / match None::<()> { LL | | Some(_) => false, LL | | None => true, LL | | }; - | |_____^ help: try this: `None::<()>.is_none()` + | |_____^ help: try: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:101:12 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:106:12 +======= + --> $DIR/redundant_pattern_matching_option.rs:104:12 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_option.rs:105:12 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:106:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/redundant_pattern_matching_option.rs:103:12 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | if let None = *(&None::<()>) {} - | -------^^^^----------------- help: try this: `if (&None::<()>).is_none()` + | -------^^^^----------------- help: try: `if (&None::<()>).is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching_option.rs:102:12 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:107:12 +======= + --> $DIR/redundant_pattern_matching_option.rs:105:12 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_option.rs:106:12 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:107:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/redundant_pattern_matching_option.rs:104:12 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | if let None = *&None::<()> {} - | -------^^^^--------------- help: try this: `if (&None::<()>).is_none()` + | -------^^^^--------------- help: try: `if (&None::<()>).is_none()` + +<<<<<<< HEAD +error: redundant pattern matching, consider using `is_some()` +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_option.rs:113:5 + | +LL | / match x { +LL | | Some(_) => true, +LL | | _ => false, +LL | | }; + | |_____^ help: try: `x.is_some()` + +error: redundant pattern matching, consider using `is_none()` + --> $DIR/redundant_pattern_matching_option.rs:118:5 + | +LL | / match x { +LL | | None => true, +LL | | _ => false, +LL | | }; + | |_____^ help: try: `x.is_none()` + +error: redundant pattern matching, consider using `is_none()` + --> $DIR/redundant_pattern_matching_option.rs:123:5 + | +LL | / match x { +LL | | Some(_) => false, +LL | | _ => true, +LL | | }; + | |_____^ help: try: `x.is_none()` + +error: redundant pattern matching, consider using `is_some()` + --> $DIR/redundant_pattern_matching_option.rs:128:5 + | +LL | / match x { +LL | | None => false, +LL | | _ => true, +LL | | }; + | |_____^ help: try: `x.is_some()` + +error: redundant pattern matching, consider using `is_some()` + --> $DIR/redundant_pattern_matching_option.rs:143:13 + | +LL | let _ = matches!(x, Some(_)); + | ^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_some()` + +error: redundant pattern matching, consider using `is_none()` + --> $DIR/redundant_pattern_matching_option.rs:145:13 + | +LL | let _ = matches!(x, None); + | ^^^^^^^^^^^^^^^^^ help: try: `x.is_none()` + +error: aborting due to 28 previous errors +======= + --> $DIR/redundant_pattern_matching_option.rs:109:5 +======= + --> $DIR/redundant_pattern_matching_option.rs:112:5 +>>>>>>> c53ceba56 (update tests) +======= + --> $DIR/redundant_pattern_matching_option.rs:111:5 +>>>>>>> 79a8867ad (update test option) +======= + --> $DIR/redundant_pattern_matching_option.rs:112:5 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_option.rs:113:5 +>>>>>>> 26f50395b (Add `needless_if` lint) + | +LL | / match x { +LL | | Some(_) => true, +LL | | _ => false, +LL | | }; + | |_____^ help: try this: `x.is_some()` + +error: redundant pattern matching, consider using `is_none()` + --> $DIR/redundant_pattern_matching_option.rs:118:5 + | +LL | / match x { +LL | | None => true, +LL | | _ => false, +LL | | }; + | |_____^ help: try this: `x.is_none()` + +<<<<<<< HEAD +error: redundant pattern matching, consider using `is_some()` + --> $DIR/redundant_pattern_matching_option.rs:122:5 + | +LL | / match y { +LL | | Some(_) => true, +LL | | _ => false, +LL | | }; + | |_____^ help: try this: `y.is_some()` + +<<<<<<< HEAD +error: aborting due to 30 previous errors +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= +======= +>>>>>>> 79a8867ad (update test option) +error: redundant pattern matching, consider using `is_none()` + --> $DIR/redundant_pattern_matching_option.rs:123:5 + | +LL | / match x { +LL | | Some(_) => false, +LL | | _ => true, +LL | | }; + | |_____^ help: try this: `x.is_none()` + +error: redundant pattern matching, consider using `is_some()` + --> $DIR/redundant_pattern_matching_option.rs:128:5 + | +LL | / match x { +LL | | None => false, +LL | | _ => true, +LL | | }; + | |_____^ help: try this: `x.is_some()` + +<<<<<<< HEAD +error: aborting due to 26 previous errors +>>>>>>> 342ce3da0 (fix reviewer comments) +======= +error: redundant pattern matching, consider using `is_some()` + --> $DIR/redundant_pattern_matching_option.rs:143:13 + | +LL | let _ = matches!(x, Some(_)); + | ^^^^^^^^^^^^^^^^^^^^ help: try this: `x.is_some()` + +error: redundant pattern matching, consider using `is_none()` + --> $DIR/redundant_pattern_matching_option.rs:145:13 + | +LL | let _ = matches!(x, None); + | ^^^^^^^^^^^^^^^^^ help: try this: `x.is_none()` -error: aborting due to 21 previous errors +error: aborting due to 28 previous errors +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= +error: aborting due to 22 previous errors +>>>>>>> e4f5d83fa (Fixed formatting.) diff --git a/tests/ui/redundant_pattern_matching_poll.fixed b/tests/ui/redundant_pattern_matching_poll.fixed index 3645f2c4bfdd..f739deaf58ea 100644 --- a/tests/ui/redundant_pattern_matching_poll.fixed +++ b/tests/ui/redundant_pattern_matching_poll.fixed @@ -1,10 +1,11 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow( unused_must_use, clippy::needless_bool, + clippy::needless_if, clippy::match_like_matches_macro, clippy::equatable_if_let, clippy::if_same_then_else diff --git a/tests/ui/redundant_pattern_matching_poll.rs b/tests/ui/redundant_pattern_matching_poll.rs index 866c71b7cfa8..88dde02b38b7 100644 --- a/tests/ui/redundant_pattern_matching_poll.rs +++ b/tests/ui/redundant_pattern_matching_poll.rs @@ -1,10 +1,11 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow( unused_must_use, clippy::needless_bool, + clippy::needless_if, clippy::match_like_matches_macro, clippy::equatable_if_let, clippy::if_same_then_else diff --git a/tests/ui/redundant_pattern_matching_poll.stderr b/tests/ui/redundant_pattern_matching_poll.stderr index 1b480f3157f7..28d3606c4fb6 100644 --- a/tests/ui/redundant_pattern_matching_poll.stderr +++ b/tests/ui/redundant_pattern_matching_poll.stderr @@ -1,128 +1,128 @@ error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_poll.rs:16:12 + --> $DIR/redundant_pattern_matching_poll.rs:17:12 | LL | if let Pending = Pending::<()> {} - | -------^^^^^^^---------------- help: try this: `if Pending::<()>.is_pending()` + | -------^^^^^^^---------------- help: try: `if Pending::<()>.is_pending()` | = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_poll.rs:18:12 + --> $DIR/redundant_pattern_matching_poll.rs:19:12 | LL | if let Ready(_) = Ready(42) {} - | -------^^^^^^^^------------ help: try this: `if Ready(42).is_ready()` + | -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_poll.rs:20:12 + --> $DIR/redundant_pattern_matching_poll.rs:21:12 | LL | if let Ready(_) = Ready(42) { - | -------^^^^^^^^------------ help: try this: `if Ready(42).is_ready()` + | -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_poll.rs:26:15 + --> $DIR/redundant_pattern_matching_poll.rs:27:15 | LL | while let Ready(_) = Ready(42) {} - | ----------^^^^^^^^------------ help: try this: `while Ready(42).is_ready()` + | ----------^^^^^^^^------------ help: try: `while Ready(42).is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_poll.rs:28:15 + --> $DIR/redundant_pattern_matching_poll.rs:29:15 | LL | while let Pending = Ready(42) {} - | ----------^^^^^^^------------ help: try this: `while Ready(42).is_pending()` + | ----------^^^^^^^------------ help: try: `while Ready(42).is_pending()` error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_poll.rs:30:15 + --> $DIR/redundant_pattern_matching_poll.rs:31:15 | LL | while let Pending = Pending::<()> {} - | ----------^^^^^^^---------------- help: try this: `while Pending::<()>.is_pending()` + | ----------^^^^^^^---------------- help: try: `while Pending::<()>.is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_poll.rs:36:5 + --> $DIR/redundant_pattern_matching_poll.rs:37:5 | LL | / match Ready(42) { LL | | Ready(_) => true, LL | | Pending => false, LL | | }; - | |_____^ help: try this: `Ready(42).is_ready()` + | |_____^ help: try: `Ready(42).is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_poll.rs:41:5 + --> $DIR/redundant_pattern_matching_poll.rs:42:5 | LL | / match Pending::<()> { LL | | Ready(_) => false, LL | | Pending => true, LL | | }; - | |_____^ help: try this: `Pending::<()>.is_pending()` + | |_____^ help: try: `Pending::<()>.is_pending()` error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_poll.rs:46:13 + --> $DIR/redundant_pattern_matching_poll.rs:47:13 | LL | let _ = match Pending::<()> { | _____________^ LL | | Ready(_) => false, LL | | Pending => true, LL | | }; - | |_____^ help: try this: `Pending::<()>.is_pending()` + | |_____^ help: try: `Pending::<()>.is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_poll.rs:52:20 + --> $DIR/redundant_pattern_matching_poll.rs:53:20 | LL | let _ = if let Ready(_) = poll { true } else { false }; - | -------^^^^^^^^------- help: try this: `if poll.is_ready()` + | -------^^^^^^^^------- help: try: `if poll.is_ready()` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_poll.rs:56:20 + --> $DIR/redundant_pattern_matching_poll.rs:57:20 | LL | let _ = if let Ready(_) = gen_poll() { - | -------^^^^^^^^------------- help: try this: `if gen_poll().is_ready()` + | -------^^^^^^^^------------- help: try: `if gen_poll().is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_poll.rs:58:19 + --> $DIR/redundant_pattern_matching_poll.rs:59:19 | LL | } else if let Pending = gen_poll() { - | -------^^^^^^^------------- help: try this: `if gen_poll().is_pending()` + | -------^^^^^^^------------- help: try: `if gen_poll().is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_poll.rs:74:12 + --> $DIR/redundant_pattern_matching_poll.rs:75:12 | LL | if let Ready(_) = Ready(42) {} - | -------^^^^^^^^------------ help: try this: `if Ready(42).is_ready()` + | -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_poll.rs:76:12 + --> $DIR/redundant_pattern_matching_poll.rs:77:12 | LL | if let Pending = Pending::<()> {} - | -------^^^^^^^---------------- help: try this: `if Pending::<()>.is_pending()` + | -------^^^^^^^---------------- help: try: `if Pending::<()>.is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_poll.rs:78:15 + --> $DIR/redundant_pattern_matching_poll.rs:79:15 | LL | while let Ready(_) = Ready(42) {} - | ----------^^^^^^^^------------ help: try this: `while Ready(42).is_ready()` + | ----------^^^^^^^^------------ help: try: `while Ready(42).is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_poll.rs:80:15 + --> $DIR/redundant_pattern_matching_poll.rs:81:15 | LL | while let Pending = Pending::<()> {} - | ----------^^^^^^^---------------- help: try this: `while Pending::<()>.is_pending()` + | ----------^^^^^^^---------------- help: try: `while Pending::<()>.is_pending()` error: redundant pattern matching, consider using `is_ready()` - --> $DIR/redundant_pattern_matching_poll.rs:82:5 + --> $DIR/redundant_pattern_matching_poll.rs:83:5 | LL | / match Ready(42) { LL | | Ready(_) => true, LL | | Pending => false, LL | | }; - | |_____^ help: try this: `Ready(42).is_ready()` + | |_____^ help: try: `Ready(42).is_ready()` error: redundant pattern matching, consider using `is_pending()` - --> $DIR/redundant_pattern_matching_poll.rs:87:5 + --> $DIR/redundant_pattern_matching_poll.rs:88:5 | LL | / match Pending::<()> { LL | | Ready(_) => false, LL | | Pending => true, LL | | }; - | |_____^ help: try this: `Pending::<()>.is_pending()` + | |_____^ help: try: `Pending::<()>.is_pending()` error: aborting due to 18 previous errors diff --git a/tests/ui/redundant_pattern_matching_result.fixed b/tests/ui/redundant_pattern_matching_result.fixed index 42348df4480b..597f8c7faa0d 100644 --- a/tests/ui/redundant_pattern_matching_result.fixed +++ b/tests/ui/redundant_pattern_matching_result.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow(deprecated, unused_must_use)] @@ -6,6 +6,7 @@ clippy::if_same_then_else, clippy::match_like_matches_macro, clippy::needless_bool, + clippy::needless_if, clippy::uninlined_format_args, clippy::unnecessary_wraps )] @@ -43,6 +44,15 @@ fn main() { issue5504(); issue6067(); issue6065(); + issue10726(); +<<<<<<< HEAD +<<<<<<< HEAD + issue10803(); +======= +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + issue10803(); +>>>>>>> 0b507c6f0 (redundant pattern matches! result) let _ = if gen_res().is_ok() { 1 @@ -107,3 +117,84 @@ const fn issue6067() { Err::(42).is_err(); } + +fn issue10726() { +<<<<<<< HEAD +<<<<<<< HEAD + // This is optional, but it makes the examples easier + let x: Result = Ok(42); + + x.is_ok(); + + x.is_err(); + + x.is_err(); + + x.is_ok(); + + // Don't lint + match x { + Err(16) => false, + _ => true, + }; + + // Don't lint + match x { + Ok(16) => false, + _ => true, + }; +} + +fn issue10803() { + let x: Result = Ok(42); + + let _ = x.is_ok(); + + let _ = x.is_err(); + + // Don't lint + let _ = matches!(x, Ok(16)); + + // Don't lint + let _ = matches!(x, Err(16)); +<<<<<<< HEAD +======= + Ok::(42).is_ok(); +======= + // This is optional, but it makes the examples easier + let x: Result = Ok(42); +>>>>>>> 3991dd10b (fix reviewer comments: tests results) + + x.is_ok(); + + x.is_err(); + + x.is_err(); + +<<<<<<< HEAD +<<<<<<< HEAD + Err::(42).is_ok(); +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + match Ok::(42) { + Ok(21) => true, + _ => false, +======= + x.is_ok(); + + // Don't lint + match x { + Err(16) => false, + _ => true, + }; + + // Don't lint + match x { + Ok(16) => false, + _ => true, +>>>>>>> 3991dd10b (fix reviewer comments: tests results) + }; +>>>>>>> 342ce3da0 (fix reviewer comments) +======= +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +} diff --git a/tests/ui/redundant_pattern_matching_result.rs b/tests/ui/redundant_pattern_matching_result.rs index 5949cb2271c6..0e4352515906 100644 --- a/tests/ui/redundant_pattern_matching_result.rs +++ b/tests/ui/redundant_pattern_matching_result.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow(deprecated, unused_must_use)] @@ -6,6 +6,7 @@ clippy::if_same_then_else, clippy::match_like_matches_macro, clippy::needless_bool, + clippy::needless_if, clippy::uninlined_format_args, clippy::unnecessary_wraps )] @@ -55,6 +56,15 @@ fn main() { issue5504(); issue6067(); issue6065(); + issue10726(); +<<<<<<< HEAD +<<<<<<< HEAD + issue10803(); +======= +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + issue10803(); +>>>>>>> 0b507c6f0 (redundant pattern matches! result) let _ = if let Ok(_) = gen_res() { 1 @@ -125,3 +135,114 @@ const fn issue6067() { Err(_) => true, }; } + +fn issue10726() { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 3991dd10b (fix reviewer comments: tests results) + // This is optional, but it makes the examples easier + let x: Result = Ok(42); + + match x { +<<<<<<< HEAD +======= + match Ok::(42) { +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= +>>>>>>> 3991dd10b (fix reviewer comments: tests results) + Ok(_) => true, + _ => false, + }; + +<<<<<<< HEAD +<<<<<<< HEAD + match x { +======= + match Ok::(42) { +<<<<<<< HEAD +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + match x { +>>>>>>> 3991dd10b (fix reviewer comments: tests results) + Ok(_) => false, + _ => true, + }; + +<<<<<<< HEAD +<<<<<<< HEAD + match x { + Err(_) => true, + _ => false, + }; + + match x { + Err(_) => false, + _ => true, + }; + + // Don't lint + match x { + Err(16) => false, + _ => true, + }; + + // Don't lint + match x { + Ok(16) => false, + _ => true, + }; +} + +fn issue10803() { + let x: Result = Ok(42); + + let _ = matches!(x, Ok(_)); + + let _ = matches!(x, Err(_)); + + // Don't lint + let _ = matches!(x, Ok(16)); + + // Don't lint + let _ = matches!(x, Err(16)); +<<<<<<< HEAD +======= + match Err::(42) { + Ok(_) => false, + _ => true, + }; + + match Err::(42) { + Ok(_) => true, + _ => false, + }; +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= +======= + match x { +>>>>>>> 3991dd10b (fix reviewer comments: tests results) + Err(_) => true, + _ => false, + }; + + match x { + Err(_) => false, + _ => true, + }; + + // Don't lint + match x { + Err(16) => false, + _ => true, + }; + + // Don't lint + match x { + Ok(16) => false, + _ => true, + }; +>>>>>>> 342ce3da0 (fix reviewer comments) +======= +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +} diff --git a/tests/ui/redundant_pattern_matching_result.stderr b/tests/ui/redundant_pattern_matching_result.stderr index d6a46babb779..466355ed079e 100644 --- a/tests/ui/redundant_pattern_matching_result.stderr +++ b/tests/ui/redundant_pattern_matching_result.stderr @@ -1,154 +1,436 @@ error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_result.rs:15:12 + --> $DIR/redundant_pattern_matching_result.rs:16:12 | LL | if let Ok(_) = &result {} - | -------^^^^^---------- help: try this: `if result.is_ok()` + | -------^^^^^---------- help: try: `if result.is_ok()` | = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_result.rs:17:12 + --> $DIR/redundant_pattern_matching_result.rs:18:12 | LL | if let Ok(_) = Ok::(42) {} - | -------^^^^^--------------------- help: try this: `if Ok::(42).is_ok()` + | -------^^^^^--------------------- help: try: `if Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_result.rs:19:12 + --> $DIR/redundant_pattern_matching_result.rs:20:12 | LL | if let Err(_) = Err::(42) {} - | -------^^^^^^---------------------- help: try this: `if Err::(42).is_err()` + | -------^^^^^^---------------------- help: try: `if Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_result.rs:21:15 + --> $DIR/redundant_pattern_matching_result.rs:22:15 | LL | while let Ok(_) = Ok::(10) {} - | ----------^^^^^--------------------- help: try this: `while Ok::(10).is_ok()` + | ----------^^^^^--------------------- help: try: `while Ok::(10).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_result.rs:23:15 + --> $DIR/redundant_pattern_matching_result.rs:24:15 | LL | while let Err(_) = Ok::(10) {} - | ----------^^^^^^--------------------- help: try this: `while Ok::(10).is_err()` + | ----------^^^^^^--------------------- help: try: `while Ok::(10).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_result.rs:33:5 + --> $DIR/redundant_pattern_matching_result.rs:34:5 | LL | / match Ok::(42) { LL | | Ok(_) => true, LL | | Err(_) => false, LL | | }; - | |_____^ help: try this: `Ok::(42).is_ok()` + | |_____^ help: try: `Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_result.rs:38:5 + --> $DIR/redundant_pattern_matching_result.rs:39:5 | LL | / match Ok::(42) { LL | | Ok(_) => false, LL | | Err(_) => true, LL | | }; - | |_____^ help: try this: `Ok::(42).is_err()` + | |_____^ help: try: `Ok::(42).is_err()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_result.rs:43:5 + --> $DIR/redundant_pattern_matching_result.rs:44:5 | LL | / match Err::(42) { LL | | Ok(_) => false, LL | | Err(_) => true, LL | | }; - | |_____^ help: try this: `Err::(42).is_err()` + | |_____^ help: try: `Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_result.rs:48:5 + --> $DIR/redundant_pattern_matching_result.rs:49:5 | LL | / match Err::(42) { LL | | Ok(_) => true, LL | | Err(_) => false, LL | | }; - | |_____^ help: try this: `Err::(42).is_ok()` + | |_____^ help: try: `Err::(42).is_ok()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_result.rs:53:20 + --> $DIR/redundant_pattern_matching_result.rs:54:20 | LL | let _ = if let Ok(_) = Ok::(4) { true } else { false }; - | -------^^^^^--------------------- help: try this: `if Ok::(4).is_ok()` + | -------^^^^^--------------------- help: try: `if Ok::(4).is_ok()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_result.rs:59:20 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:62:20 +======= + --> $DIR/redundant_pattern_matching_result.rs:60:20 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:61:20 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:62:20 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | let _ = if let Ok(_) = gen_res() { - | -------^^^^^------------ help: try this: `if gen_res().is_ok()` + | -------^^^^^------------ help: try: `if gen_res().is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_result.rs:61:19 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:64:19 +======= + --> $DIR/redundant_pattern_matching_result.rs:62:19 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:63:19 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:64:19 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | } else if let Err(_) = gen_res() { - | -------^^^^^^------------ help: try this: `if gen_res().is_err()` + | -------^^^^^^------------ help: try: `if gen_res().is_err()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_result.rs:84:19 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:87:19 +======= + --> $DIR/redundant_pattern_matching_result.rs:85:19 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:86:19 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:87:19 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | while let Some(_) = r#try!(result_opt()) {} - | ----------^^^^^^^----------------------- help: try this: `while r#try!(result_opt()).is_some()` + | ----------^^^^^^^----------------------- help: try: `while r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_result.rs:85:16 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:88:16 +======= + --> $DIR/redundant_pattern_matching_result.rs:86:16 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:87:16 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:88:16 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | if let Some(_) = r#try!(result_opt()) {} - | -------^^^^^^^----------------------- help: try this: `if r#try!(result_opt()).is_some()` + | -------^^^^^^^----------------------- help: try: `if r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_result.rs:91:12 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:94:12 +======= + --> $DIR/redundant_pattern_matching_result.rs:92:12 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:93:12 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:94:12 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | if let Some(_) = m!() {} - | -------^^^^^^^------- help: try this: `if m!().is_some()` + | -------^^^^^^^------- help: try: `if m!().is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching_result.rs:92:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:95:15 +======= + --> $DIR/redundant_pattern_matching_result.rs:93:15 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:94:15 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:95:15 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | while let Some(_) = m!() {} - | ----------^^^^^^^------- help: try this: `while m!().is_some()` + | ----------^^^^^^^------- help: try: `while m!().is_some()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_result.rs:110:12 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:113:12 +======= + --> $DIR/redundant_pattern_matching_result.rs:111:12 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:112:12 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:113:12 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | if let Ok(_) = Ok::(42) {} - | -------^^^^^--------------------- help: try this: `if Ok::(42).is_ok()` + | -------^^^^^--------------------- help: try: `if Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_result.rs:112:12 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:115:12 +======= + --> $DIR/redundant_pattern_matching_result.rs:113:12 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:114:12 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:115:12 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | if let Err(_) = Err::(42) {} - | -------^^^^^^---------------------- help: try this: `if Err::(42).is_err()` + | -------^^^^^^---------------------- help: try: `if Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_result.rs:114:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:117:15 +======= + --> $DIR/redundant_pattern_matching_result.rs:115:15 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:116:15 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:117:15 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | while let Ok(_) = Ok::(10) {} - | ----------^^^^^--------------------- help: try this: `while Ok::(10).is_ok()` + | ----------^^^^^--------------------- help: try: `while Ok::(10).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_result.rs:116:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:119:15 +======= + --> $DIR/redundant_pattern_matching_result.rs:117:15 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:118:15 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:119:15 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | while let Err(_) = Ok::(10) {} - | ----------^^^^^^--------------------- help: try this: `while Ok::(10).is_err()` + | ----------^^^^^^--------------------- help: try: `while Ok::(10).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_result.rs:118:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:121:5 +======= + --> $DIR/redundant_pattern_matching_result.rs:119:5 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:120:5 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:121:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / match Ok::(42) { LL | | Ok(_) => true, LL | | Err(_) => false, LL | | }; - | |_____^ help: try this: `Ok::(42).is_ok()` + | |_____^ help: try: `Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_result.rs:123:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:126:5 +======= + --> $DIR/redundant_pattern_matching_result.rs:124:5 +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + --> $DIR/redundant_pattern_matching_result.rs:125:5 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:126:5 +>>>>>>> 26f50395b (Add `needless_if` lint) | LL | / match Err::(42) { LL | | Ok(_) => false, LL | | Err(_) => true, +LL | | }; + | |_____^ help: try: `Err::(42).is_err()` + +error: redundant pattern matching, consider using `is_ok()` +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_pattern_matching_result.rs:136:5 + | +LL | / match x { +LL | | Ok(_) => true, +LL | | _ => false, +LL | | }; +<<<<<<< HEAD + | |_____^ help: try this: `x.is_ok()` +======= + --> $DIR/redundant_pattern_matching_result.rs:131:5 +======= + --> $DIR/redundant_pattern_matching_result.rs:134:5 +>>>>>>> 3991dd10b (fix reviewer comments: tests results) +======= + --> $DIR/redundant_pattern_matching_result.rs:135:5 +>>>>>>> 0b507c6f0 (redundant pattern matches! result) +======= + --> $DIR/redundant_pattern_matching_result.rs:136:5 +>>>>>>> 26f50395b (Add `needless_if` lint) + | +LL | / match x { +LL | | Ok(_) => true, +LL | | _ => false, +LL | | }; + | |_____^ help: try this: `x.is_ok()` +======= + | |_____^ help: try: `x.is_ok()` +>>>>>>> 420f3d11e ("try this" -> "try") + +error: redundant pattern matching, consider using `is_err()` + --> $DIR/redundant_pattern_matching_result.rs:141:5 + | +LL | / match x { +LL | | Ok(_) => false, +LL | | _ => true, +LL | | }; + | |_____^ help: try: `x.is_err()` + +error: redundant pattern matching, consider using `is_err()` + --> $DIR/redundant_pattern_matching_result.rs:146:5 + | +LL | / match x { +LL | | Err(_) => true, +LL | | _ => false, +LL | | }; +<<<<<<< HEAD +<<<<<<< HEAD + | |_____^ help: try this: `Ok::(42).is_err()` +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= + | |_____^ help: try this: `x.is_err()` +>>>>>>> 3991dd10b (fix reviewer comments: tests results) + +<<<<<<< HEAD +error: redundant pattern matching, consider using `is_err()` + --> $DIR/redundant_pattern_matching_result.rs:141:5 + | +<<<<<<< HEAD +LL | / match x { +LL | | Ok(_) => false, +LL | | _ => true, +LL | | }; + | |_____^ help: try this: `x.is_err()` + +error: redundant pattern matching, consider using `is_err()` + --> $DIR/redundant_pattern_matching_result.rs:146:5 + | +LL | / match x { +LL | | Err(_) => true, +LL | | _ => false, +LL | | }; + | |_____^ help: try this: `x.is_err()` +======= + | |_____^ help: try: `x.is_err()` +>>>>>>> 420f3d11e ("try this" -> "try") + +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/redundant_pattern_matching_result.rs:151:5 + | +LL | / match x { +LL | | Err(_) => false, +LL | | _ => true, +LL | | }; + | |_____^ help: try: `x.is_ok()` + +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/redundant_pattern_matching_result.rs:172:13 + | +LL | let _ = matches!(x, Ok(_)); + | ^^^^^^^^^^^^^^^^^^ help: try: `x.is_ok()` + +error: redundant pattern matching, consider using `is_err()` + --> $DIR/redundant_pattern_matching_result.rs:174:13 + | +LL | let _ = matches!(x, Err(_)); + | ^^^^^^^^^^^^^^^^^^^ help: try: `x.is_err()` + +error: aborting due to 28 previous errors +======= +LL | / match Err::(42) { +LL | | Ok(_) => false, +LL | | _ => true, LL | | }; | |_____^ help: try this: `Err::(42).is_err()` -error: aborting due to 22 previous errors +======= +>>>>>>> 342ce3da0 (fix reviewer comments) +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/redundant_pattern_matching_result.rs:151:5 + | +LL | / match x { +LL | | Err(_) => false, +LL | | _ => true, +LL | | }; + | |_____^ help: try this: `x.is_ok()` + +<<<<<<< HEAD +error: aborting due to 26 previous errors +>>>>>>> afa2741e6 (redundant_pattern_matching) +======= +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/redundant_pattern_matching_result.rs:172:13 + | +LL | let _ = matches!(x, Ok(_)); + | ^^^^^^^^^^^^^^^^^^ help: try this: `x.is_ok()` + +error: redundant pattern matching, consider using `is_err()` + --> $DIR/redundant_pattern_matching_result.rs:174:13 + | +LL | let _ = matches!(x, Err(_)); + | ^^^^^^^^^^^^^^^^^^^ help: try this: `x.is_err()` + +error: aborting due to 28 previous errors +>>>>>>> 0b507c6f0 (redundant pattern matches! result) diff --git a/tests/ui/redundant_pub_crate.fixed b/tests/ui/redundant_pub_crate.fixed index 106947de68c1..a1ed491bbc6e 100644 --- a/tests/ui/redundant_pub_crate.fixed +++ b/tests/ui/redundant_pub_crate.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::redundant_pub_crate)] @@ -14,7 +14,7 @@ mod m1 { } pub mod m1_2 { - // ^ private due to m1 + //:^ private due to m1 fn f() {} pub fn g() {} // private due to m1_2 and m1 pub fn h() {} @@ -39,7 +39,7 @@ pub(crate) mod m2 { } pub mod m2_2 { - // ^ already crate visible due to m2 + //:^ already crate visible due to m2 fn f() {} pub fn g() {} // already crate visible due to m2_2 and m2 pub fn h() {} @@ -64,7 +64,7 @@ pub mod m3 { } pub(crate) mod m3_2 { - // ^ ok + //:^ ok fn f() {} pub fn g() {} // already crate visible due to m3_2 pub fn h() {} @@ -89,7 +89,7 @@ mod m4 { } pub mod m4_2 { - // ^ private: not re-exported by `pub use m4::*` + //:^ private: not re-exported by `pub use m4::*` fn f() {} pub fn g() {} // private due to m4_2 pub fn h() {} diff --git a/tests/ui/redundant_pub_crate.rs b/tests/ui/redundant_pub_crate.rs index f96cfd318438..9accd297fc93 100644 --- a/tests/ui/redundant_pub_crate.rs +++ b/tests/ui/redundant_pub_crate.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::redundant_pub_crate)] @@ -14,7 +14,7 @@ mod m1 { } pub(crate) mod m1_2 { - // ^ private due to m1 + //:^ private due to m1 fn f() {} pub(crate) fn g() {} // private due to m1_2 and m1 pub fn h() {} @@ -39,7 +39,7 @@ pub(crate) mod m2 { } pub(crate) mod m2_2 { - // ^ already crate visible due to m2 + //:^ already crate visible due to m2 fn f() {} pub(crate) fn g() {} // already crate visible due to m2_2 and m2 pub fn h() {} @@ -64,7 +64,7 @@ pub mod m3 { } pub(crate) mod m3_2 { - // ^ ok + //:^ ok fn f() {} pub(crate) fn g() {} // already crate visible due to m3_2 pub fn h() {} @@ -89,7 +89,7 @@ mod m4 { } pub(crate) mod m4_2 { - // ^ private: not re-exported by `pub use m4::*` + //:^ private: not re-exported by `pub use m4::*` fn f() {} pub(crate) fn g() {} // private due to m4_2 pub fn h() {} diff --git a/tests/ui/redundant_slicing.fixed b/tests/ui/redundant_slicing.fixed index 8dd8d3092378..56ddca71903e 100644 --- a/tests/ui/redundant_slicing.fixed +++ b/tests/ui/redundant_slicing.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::deref_by_slicing)] #![warn(clippy::redundant_slicing)] diff --git a/tests/ui/redundant_slicing.rs b/tests/ui/redundant_slicing.rs index 51c16dd8d65a..d67b6665e260 100644 --- a/tests/ui/redundant_slicing.rs +++ b/tests/ui/redundant_slicing.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::deref_by_slicing)] #![warn(clippy::redundant_slicing)] diff --git a/tests/ui/redundant_static_lifetimes.fixed b/tests/ui/redundant_static_lifetimes.fixed index bca777a890c3..a83699ec68da 100644 --- a/tests/ui/redundant_static_lifetimes.fixed +++ b/tests/ui/redundant_static_lifetimes.fixed @@ -1,43 +1,43 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #[derive(Debug)] struct Foo; -const VAR_ONE: &str = "Test constant #1"; // ERROR Consider removing 'static. +const VAR_ONE: &str = "Test constant #1"; // ERROR: Consider removing 'static. const VAR_TWO: &str = "Test constant #2"; // This line should not raise a warning. -const VAR_THREE: &[&str] = &["one", "two"]; // ERROR Consider removing 'static +const VAR_THREE: &[&str] = &["one", "two"]; // ERROR: Consider removing 'static -const VAR_FOUR: (&str, (&str, &str), &str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static +const VAR_FOUR: (&str, (&str, &str), &str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static const VAR_SIX: &u8 = &5; const VAR_HEIGHT: &Foo = &Foo {}; -const VAR_SLICE: &[u8] = b"Test constant #1"; // ERROR Consider removing 'static. +const VAR_SLICE: &[u8] = b"Test constant #1"; // ERROR: Consider removing 'static. -const VAR_TUPLE: &(u8, u8) = &(1, 2); // ERROR Consider removing 'static. +const VAR_TUPLE: &(u8, u8) = &(1, 2); // ERROR: Consider removing 'static. -const VAR_ARRAY: &[u8; 1] = b"T"; // ERROR Consider removing 'static. +const VAR_ARRAY: &[u8; 1] = b"T"; // ERROR: Consider removing 'static. -static STATIC_VAR_ONE: &str = "Test static #1"; // ERROR Consider removing 'static. +static STATIC_VAR_ONE: &str = "Test static #1"; // ERROR: Consider removing 'static. static STATIC_VAR_TWO: &str = "Test static #2"; // This line should not raise a warning. -static STATIC_VAR_THREE: &[&str] = &["one", "two"]; // ERROR Consider removing 'static +static STATIC_VAR_THREE: &[&str] = &["one", "two"]; // ERROR: Consider removing 'static static STATIC_VAR_SIX: &u8 = &5; static STATIC_VAR_HEIGHT: &Foo = &Foo {}; -static STATIC_VAR_SLICE: &[u8] = b"Test static #3"; // ERROR Consider removing 'static. +static STATIC_VAR_SLICE: &[u8] = b"Test static #3"; // ERROR: Consider removing 'static. -static STATIC_VAR_TUPLE: &(u8, u8) = &(1, 2); // ERROR Consider removing 'static. +static STATIC_VAR_TUPLE: &(u8, u8) = &(1, 2); // ERROR: Consider removing 'static. -static STATIC_VAR_ARRAY: &[u8; 1] = b"T"; // ERROR Consider removing 'static. +static STATIC_VAR_ARRAY: &[u8; 1] = b"T"; // ERROR: Consider removing 'static. static mut STATIC_MUT_SLICE: &mut [u32] = &mut [0]; diff --git a/tests/ui/redundant_static_lifetimes.rs b/tests/ui/redundant_static_lifetimes.rs index afe7644816d2..b165cbaa3aa1 100644 --- a/tests/ui/redundant_static_lifetimes.rs +++ b/tests/ui/redundant_static_lifetimes.rs @@ -1,43 +1,43 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #[derive(Debug)] struct Foo; -const VAR_ONE: &'static str = "Test constant #1"; // ERROR Consider removing 'static. +const VAR_ONE: &'static str = "Test constant #1"; // ERROR: Consider removing 'static. const VAR_TWO: &str = "Test constant #2"; // This line should not raise a warning. -const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR Consider removing 'static +const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static -const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static +const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static const VAR_SIX: &'static u8 = &5; const VAR_HEIGHT: &'static Foo = &Foo {}; -const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR Consider removing 'static. +const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR: Consider removing 'static. -const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR Consider removing 'static. +const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static. -const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR Consider removing 'static. +const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static. -static STATIC_VAR_ONE: &'static str = "Test static #1"; // ERROR Consider removing 'static. +static STATIC_VAR_ONE: &'static str = "Test static #1"; // ERROR: Consider removing 'static. static STATIC_VAR_TWO: &str = "Test static #2"; // This line should not raise a warning. -static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR Consider removing 'static +static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static static STATIC_VAR_SIX: &'static u8 = &5; static STATIC_VAR_HEIGHT: &'static Foo = &Foo {}; -static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR Consider removing 'static. +static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR: Consider removing 'static. -static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR Consider removing 'static. +static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static. -static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR Consider removing 'static. +static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static. static mut STATIC_MUT_SLICE: &'static mut [u32] = &mut [0]; diff --git a/tests/ui/redundant_static_lifetimes.stderr b/tests/ui/redundant_static_lifetimes.stderr index b2cbd2d9d01b..a13e5eadf15d 100644 --- a/tests/ui/redundant_static_lifetimes.stderr +++ b/tests/ui/redundant_static_lifetimes.stderr @@ -1,7 +1,7 @@ error: constants have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:8:17 | -LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR Consider removing 'static. +LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR: Consider removing 'static. | -^^^^^^^---- help: consider removing `'static`: `&str` | = note: `-D clippy::redundant-static-lifetimes` implied by `-D warnings` @@ -9,19 +9,19 @@ LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR Consider removin error: constants have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:12:21 | -LL | const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR Consider removing 'static +LL | const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: constants have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:14:32 | -LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static +LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: constants have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:14:47 | -LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static +LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: constants have by default a `'static` lifetime @@ -39,31 +39,31 @@ LL | const VAR_HEIGHT: &'static Foo = &Foo {}; error: constants have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:20:19 | -LL | const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR Consider removing 'static. +LL | const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR: Consider removing 'static. | -^^^^^^^----- help: consider removing `'static`: `&[u8]` error: constants have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:22:19 | -LL | const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR Consider removing 'static. +LL | const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static. | -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)` error: constants have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:24:19 | -LL | const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR Consider removing 'static. +LL | const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static. | -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]` error: statics have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:26:25 | -LL | static STATIC_VAR_ONE: &'static str = "Test static #1"; // ERROR Consider removing 'static. +LL | static STATIC_VAR_ONE: &'static str = "Test static #1"; // ERROR: Consider removing 'static. | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:30:29 | -LL | static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR Consider removing 'static +LL | static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime @@ -81,19 +81,19 @@ LL | static STATIC_VAR_HEIGHT: &'static Foo = &Foo {}; error: statics have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:36:27 | -LL | static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR Consider removing 'static. +LL | static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR: Consider removing 'static. | -^^^^^^^----- help: consider removing `'static`: `&[u8]` error: statics have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:38:27 | -LL | static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR Consider removing 'static. +LL | static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static. | -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)` error: statics have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes.rs:40:27 | -LL | static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR Consider removing 'static. +LL | static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static. | -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]` error: statics have by default a `'static` lifetime diff --git a/tests/ui/redundant_static_lifetimes_multiple.rs b/tests/ui/redundant_static_lifetimes_multiple.rs index f57dd58e230a..b3f263a7d66d 100644 --- a/tests/ui/redundant_static_lifetimes_multiple.rs +++ b/tests/ui/redundant_static_lifetimes_multiple.rs @@ -1,12 +1,12 @@ // these are rustfixable, but run-rustfix tests cannot handle them -const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static +const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; -static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static +static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static -static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static +static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])]; diff --git a/tests/ui/redundant_static_lifetimes_multiple.stderr b/tests/ui/redundant_static_lifetimes_multiple.stderr index cc7e55a757a3..4e7500903f81 100644 --- a/tests/ui/redundant_static_lifetimes_multiple.stderr +++ b/tests/ui/redundant_static_lifetimes_multiple.stderr @@ -1,7 +1,7 @@ error: constants have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes_multiple.rs:3:18 | -LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static +LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static | -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]` | = note: `-D clippy::redundant-static-lifetimes` implied by `-D warnings` @@ -9,7 +9,7 @@ LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; error: constants have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes_multiple.rs:3:30 | -LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static +LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: constants have by default a `'static` lifetime @@ -27,25 +27,25 @@ LL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other error: statics have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes_multiple.rs:7:40 | -LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static +LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes_multiple.rs:7:55 | -LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static +LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes_multiple.rs:9:26 | -LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static +LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static | -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]` error: statics have by default a `'static` lifetime --> $DIR/redundant_static_lifetimes_multiple.rs:9:38 | -LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static +LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static | -^^^^^^^---- help: consider removing `'static`: `&str` error: statics have by default a `'static` lifetime diff --git a/tests/ui/redundant_type_annotations.rs b/tests/ui/redundant_type_annotations.rs new file mode 100644 index 000000000000..5ff42e34aba2 --- /dev/null +++ b/tests/ui/redundant_type_annotations.rs @@ -0,0 +1,328 @@ +#![allow(unused)] +#![warn(clippy::redundant_type_annotations)] + +#[derive(Debug, Default)] +struct Cake { + _data: T, +} + +fn make_something() -> T { + T::default() +} + +fn make_cake() -> Cake { + Cake::::default() +} + +fn plus_one>(val: T) -> T { + val + 1 +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) +#[derive(Default)] +struct Slice { + inner: u32, +} + +#[derive(Default)] +struct Pie { + inner: u32, + inner_struct: Slice, +<<<<<<< HEAD +======= +struct Pie { + inner: u32, +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) +} + +enum Pizza { + One, + Two, +} + +fn return_a_string() -> String { + String::new() +} + +fn return_a_struct() -> Pie { +<<<<<<< HEAD +<<<<<<< HEAD + Pie::default() +======= + Pie { inner: 5 } +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + Pie::default() +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) +} + +fn return_an_enum() -> Pizza { + Pizza::One +} + +fn return_an_int() -> u32 { + 5 +} + +impl Pie { + fn return_an_int(&self) -> u32 { + self.inner + } + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + fn return_a_ref(&self) -> &u32 { + &self.inner + } + + fn return_a_ref_to_struct(&self) -> &Slice { + &self.inner_struct + } + +<<<<<<< HEAD +======= +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + fn associated_return_an_int() -> u32 { + 5 + } + + fn new() -> Self { +<<<<<<< HEAD +<<<<<<< HEAD + Self::default() +======= + Self { inner: 5 } +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + Self::default() +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + } + + fn associated_return_a_string() -> String { + String::from("") + } + + fn test_method_call(&self) { +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + // Everything here should be lint + + let v: u32 = self.return_an_int(); + let v: &u32 = self.return_a_ref(); + let v: &Slice = self.return_a_ref_to_struct(); +<<<<<<< HEAD +======= + let v: u32 = self.return_an_int(); // Should lint +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + } +} + +fn test_generics() { + // The type annotation is needed to determine T + let _c: Cake = make_something(); + + // The type annotation is needed to determine the topic + let _c: Cake = make_cake(); + +<<<<<<< HEAD +<<<<<<< HEAD + // This could be lint, but currently doesn't + let _c: Cake = make_cake::(); + + // This could be lint, but currently doesn't + let _c: u8 = make_something::(); + + // This could be lint, but currently doesn't +======= + // This should lint (doesn't) +======= + // This could be lint, but currently doesn't +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + let _c: Cake = make_cake::(); + + // This could be lint, but currently doesn't + let _c: u8 = make_something::(); + +<<<<<<< HEAD + // This should lint (doesn't) +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + // This could be lint, but currently doesn't +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + let _c: u8 = plus_one(5_u8); + + // Annotation needed otherwise T is i32 + let _c: u8 = plus_one(5); +<<<<<<< HEAD +<<<<<<< HEAD + + // This could be lint, but currently doesn't + let _return: String = String::from("test"); +} + +fn test_non_locals() { + // This shouldn't be lint +======= +} + +fn test_non_locals() { + // This shouldn't lint +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + + // This could be lint, but currently doesn't + let _return: String = String::from("test"); +} + +fn test_non_locals() { + // This shouldn't be lint +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + fn _arg(x: u32) -> u32 { + x + } + + // This could lint, but probably shouldn't + let _closure_arg = |x: u32| x; +} + +fn test_complex_types() { +<<<<<<< HEAD +<<<<<<< HEAD + // Shouldn't be lint, since the literal will be i32 otherwise + let _u8: u8 = 128; + + // This could be lint, but currently doesn't + let _tuple_i32: (i32, i32) = (12, 13); + + // Shouldn't be lint, since the tuple will be i32 otherwise + let _tuple_u32: (u32, u32) = (1, 2); + + // Should be lint, since the type is determined by the init value, but currently doesn't + let _tuple_u32: (u32, u32) = (3_u32, 4_u32); + + // This could be lint, but currently doesn't + let _array: [i32; 3] = [5, 6, 7]; + + // Shouldn't be lint +======= + // Shouldn't lint, since the literal will be i32 otherwise +======= + // Shouldn't be lint, since the literal will be i32 otherwise +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + let _u8: u8 = 128; + + // This could be lint, but currently doesn't + let _tuple_i32: (i32, i32) = (12, 13); + + // Shouldn't be lint, since the tuple will be i32 otherwise + let _tuple_u32: (u32, u32) = (1, 2); + + // Should be lint, since the type is determined by the init value, but currently doesn't + let _tuple_u32: (u32, u32) = (3_u32, 4_u32); + + // This could be lint, but currently doesn't + let _array: [i32; 3] = [5, 6, 7]; + +<<<<<<< HEAD + // Shouldn't lint +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + // Shouldn't be lint +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + let _array: [u32; 2] = [8, 9]; +} + +fn test_functions() { +<<<<<<< HEAD +<<<<<<< HEAD + // Everything here should be lint +======= + // Everything here should lint +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + // Everything here should be lint +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + + let _return: String = return_a_string(); + + let _return: Pie = return_a_struct(); + + let _return: Pizza = return_an_enum(); + + let _return: u32 = return_an_int(); + + let _return: String = String::new(); + + let new_pie: Pie = Pie::new(); + + let _return: u32 = new_pie.return_an_int(); + +<<<<<<< HEAD +<<<<<<< HEAD +======= + let _return: String = String::from("test"); + +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + let _return: u32 = Pie::associated_return_an_int(); + + let _return: String = Pie::associated_return_a_string(); +} + +fn test_simple_types() { +<<<<<<< HEAD +<<<<<<< HEAD + // Everything here should be lint + + let _var: u32 = u32::MAX; + + let _var: u32 = 5_u32; + + let _var: &str = "test"; + + let _var: &[u8] = b"test"; + +======= +======= + // Everything here should be lint + +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + let _var: u32 = u32::MAX; + + let _var: u32 = 5_u32; + + let _var: &str = "test"; + + let _var: &[u8] = b"test"; + +<<<<<<< HEAD + // Should lint +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + let _var: bool = false; +} + +fn main() {} +<<<<<<< HEAD +<<<<<<< HEAD +======= + +// TODO: test refs +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) diff --git a/tests/ui/redundant_type_annotations.stderr b/tests/ui/redundant_type_annotations.stderr new file mode 100644 index 000000000000..9e1b53fd055e --- /dev/null +++ b/tests/ui/redundant_type_annotations.stderr @@ -0,0 +1,240 @@ +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:81:9 + | +LL | let v: u32 = self.return_an_int(); +======= + --> $DIR/redundant_type_annotations.rs:64:9 + | +LL | let v: u32 = self.return_an_int(); // Should lint +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:81:9 + | +LL | let v: u32 = self.return_an_int(); +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::redundant-type-annotations` implied by `-D warnings` + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + --> $DIR/redundant_type_annotations.rs:82:9 + | +LL | let v: &u32 = self.return_a_ref(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation + --> $DIR/redundant_type_annotations.rs:83:9 + | +LL | let v: &Slice = self.return_a_ref_to_struct(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation + --> $DIR/redundant_type_annotations.rs:143:5 +<<<<<<< HEAD +======= + --> $DIR/redundant_type_annotations.rs:121:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _return: String = return_a_string(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:145:5 +======= + --> $DIR/redundant_type_annotations.rs:123:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:145:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _return: Pie = return_a_struct(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:147:5 +======= + --> $DIR/redundant_type_annotations.rs:125:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:147:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _return: Pizza = return_an_enum(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:149:5 +======= + --> $DIR/redundant_type_annotations.rs:127:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:149:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _return: u32 = return_an_int(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:151:5 +======= + --> $DIR/redundant_type_annotations.rs:129:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:151:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _return: String = String::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:153:5 +======= + --> $DIR/redundant_type_annotations.rs:131:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:153:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let new_pie: Pie = Pie::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:155:5 +======= + --> $DIR/redundant_type_annotations.rs:133:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:155:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _return: u32 = new_pie.return_an_int(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:157:5 +======= + --> $DIR/redundant_type_annotations.rs:137:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:157:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _return: u32 = Pie::associated_return_an_int(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:159:5 +======= + --> $DIR/redundant_type_annotations.rs:139:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:159:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _return: String = Pie::associated_return_a_string(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:165:5 +======= + --> $DIR/redundant_type_annotations.rs:143:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:165:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _var: u32 = u32::MAX; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:167:5 +======= + --> $DIR/redundant_type_annotations.rs:146:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:167:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _var: u32 = 5_u32; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:169:5 +======= + --> $DIR/redundant_type_annotations.rs:149:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:169:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _var: &str = "test"; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:171:5 +======= + --> $DIR/redundant_type_annotations.rs:152:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:171:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _var: &[u8] = b"test"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/redundant_type_annotations.rs:173:5 +======= + --> $DIR/redundant_type_annotations.rs:155:5 +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= + --> $DIR/redundant_type_annotations.rs:173:5 +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + | +LL | let _var: bool = false; + | ^^^^^^^^^^^^^^^^^^^^^^^ + +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 17 previous errors +======= +error: aborting due to 15 previous errors +>>>>>>> 01b105725 (Add redundant type annotations lint) +======= +error: aborting due to 17 previous errors +>>>>>>> 29ab954a2 (Add support to returned refs from `MethodCall`) + diff --git a/tests/ui/ref_binding_to_reference.stderr b/tests/ui/ref_binding_to_reference.stderr index eb36cd516a24..016feb103df6 100644 --- a/tests/ui/ref_binding_to_reference.stderr +++ b/tests/ui/ref_binding_to_reference.stderr @@ -5,7 +5,7 @@ LL | Some(ref x) => x, | ^^^^^ | = note: `-D clippy::ref-binding-to-reference` implied by `-D warnings` -help: try this +help: try | LL | Some(x) => &x, | ~ ~~ @@ -16,7 +16,7 @@ error: this pattern creates a reference to a reference LL | Some(ref x) => { | ^^^^^ | -help: try this +help: try | LL ~ Some(x) => { LL | f1(x); @@ -30,7 +30,7 @@ error: this pattern creates a reference to a reference LL | Some(ref x) => m2!(x), | ^^^^^ | -help: try this +help: try | LL | Some(x) => m2!(&x), | ~ ~~ @@ -41,7 +41,7 @@ error: this pattern creates a reference to a reference LL | let _ = |&ref x: &&String| { | ^^^^^ | -help: try this +help: try | LL ~ let _ = |&x: &&String| { LL ~ let _: &&String = &x; @@ -53,7 +53,7 @@ error: this pattern creates a reference to a reference LL | fn f2<'a>(&ref x: &&'a String) -> &'a String { | ^^^^^ | -help: try this +help: try | LL ~ fn f2<'a>(&x: &&'a String) -> &'a String { LL ~ let _: &&String = &x; @@ -66,7 +66,7 @@ error: this pattern creates a reference to a reference LL | fn f(&ref x: &&String) { | ^^^^^ | -help: try this +help: try | LL ~ fn f(&x: &&String) { LL ~ let _: &&String = &x; @@ -78,7 +78,7 @@ error: this pattern creates a reference to a reference LL | fn f(&ref x: &&String) { | ^^^^^ | -help: try this +help: try | LL ~ fn f(&x: &&String) { LL ~ let _: &&String = &x; diff --git a/tests/ui/ref_patterns.rs b/tests/ui/ref_patterns.rs new file mode 100644 index 000000000000..c51e0bc76efd --- /dev/null +++ b/tests/ui/ref_patterns.rs @@ -0,0 +1,19 @@ +#![allow(unused)] +#![warn(clippy::ref_patterns)] + +fn use_in_pattern() { + let opt = Some(5); + match opt { + None => {}, + Some(ref opt) => {}, + } +} + +fn use_in_binding() { + let x = 5; + let ref y = x; +} + +fn use_in_parameter(ref x: i32) {} + +fn main() {} diff --git a/tests/ui/ref_patterns.stderr b/tests/ui/ref_patterns.stderr new file mode 100644 index 000000000000..aa007782683a --- /dev/null +++ b/tests/ui/ref_patterns.stderr @@ -0,0 +1,27 @@ +error: usage of ref pattern + --> $DIR/ref_patterns.rs:8:14 + | +LL | Some(ref opt) => {}, + | ^^^^^^^ + | + = help: consider using `&` for clarity instead + = note: `-D clippy::ref-patterns` implied by `-D warnings` + +error: usage of ref pattern + --> $DIR/ref_patterns.rs:14:9 + | +LL | let ref y = x; + | ^^^^^ + | + = help: consider using `&` for clarity instead + +error: usage of ref pattern + --> $DIR/ref_patterns.rs:17:21 + | +LL | fn use_in_parameter(ref x: i32) {} + | ^^^^^ + | + = help: consider using `&` for clarity instead + +error: aborting due to 3 previous errors + diff --git a/tests/ui/regex.rs b/tests/ui/regex.rs index ab8ac97a0e70..48c377c9de82 100644 --- a/tests/ui/regex.rs +++ b/tests/ui/regex.rs @@ -1,4 +1,22 @@ -#![allow(unused, clippy::needless_borrow)] +<<<<<<< HEAD +<<<<<<< HEAD +#![allow( + unused, + clippy::needless_raw_strings, + clippy::needless_raw_string_hashes, + clippy::needless_borrow +)] +======= +#![allow(unused, clippy::needless_raw_string_hashes, clippy::needless_borrow)] +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= +#![allow( + unused, + clippy::needless_raw_strings, + clippy::needless_raw_string_hashes, + clippy::needless_borrow +)] +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) #![warn(clippy::invalid_regex, clippy::trivial_regex)] extern crate regex; @@ -34,12 +52,19 @@ fn syntax_error() { let set_error = RegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]); let bset_error = BRegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]); + // These following three cases are considering valid since regex-1.8.0 let raw_string_error = Regex::new(r"[...\/...]"); let raw_string_error = Regex::new(r#"[...\/...]"#); + let _ = Regex::new(r"(?hi)").unwrap(); let escaped_string_span = Regex::new("\\b\\c"); let aux_span = Regex::new("(?ixi)"); + + let should_not_lint = Regex::new("(?u)."); + let should_not_lint = BRegex::new("(?u)."); + let invalid_utf8_should_not_lint = BRegex::new("(?-u)."); + let invalid_utf8_should_lint = Regex::new("(?-u)."); } fn trivial_regex() { @@ -69,6 +94,8 @@ fn trivial_regex() { // non-trivial regexes let non_trivial_dot = Regex::new("a.b"); let non_trivial_dot_builder = RegexBuilder::new("a.b"); + let non_trivial_dot = Regex::new("."); + let non_trivial_dot = BRegex::new("."); let non_trivial_eq = Regex::new("^foo|bar$"); let non_trivial_starts_with = Regex::new("^foo|bar"); let non_trivial_ends_with = Regex::new("^foo|bar"); diff --git a/tests/ui/regex.stderr b/tests/ui/regex.stderr index c2440f39e0a0..96723033be07 100644 --- a/tests/ui/regex.stderr +++ b/tests/ui/regex.stderr @@ -1,5 +1,5 @@ error: trivial regex - --> $DIR/regex.rs:13:45 + --> $DIR/regex.rs:18:45 | LL | let pipe_in_wrong_position = Regex::new("|"); | ^^^ @@ -8,7 +8,7 @@ LL | let pipe_in_wrong_position = Regex::new("|"); = note: `-D clippy::trivial-regex` implied by `-D warnings` error: trivial regex - --> $DIR/regex.rs:14:60 + --> $DIR/regex.rs:19:60 | LL | let pipe_in_wrong_position_builder = RegexBuilder::new("|"); | ^^^ @@ -16,7 +16,7 @@ LL | let pipe_in_wrong_position_builder = RegexBuilder::new("|"); = help: the regex is unlikely to be useful as it is error: regex syntax error: invalid character class range, the start must be <= the end - --> $DIR/regex.rs:15:42 + --> $DIR/regex.rs:20:42 | LL | let wrong_char_ranice = Regex::new("[z-a]"); | ^^^ @@ -24,7 +24,7 @@ LL | let wrong_char_ranice = Regex::new("[z-a]"); = note: `-D clippy::invalid-regex` implied by `-D warnings` error: regex syntax error: invalid character class range, the start must be <= the end - --> $DIR/regex.rs:16:37 + --> $DIR/regex.rs:21:37 | LL | let some_unicode = Regex::new("[é-è]"); | ^^^ @@ -33,13 +33,13 @@ error: regex parse error: ( ^ error: unclosed group - --> $DIR/regex.rs:18:33 + --> $DIR/regex.rs:23:33 | LL | let some_regex = Regex::new(OPENING_PAREN); | ^^^^^^^^^^^^^ error: trivial regex - --> $DIR/regex.rs:20:53 + --> $DIR/regex.rs:25:53 | LL | let binary_pipe_in_wrong_position = BRegex::new("|"); | ^^^ @@ -50,7 +50,7 @@ error: regex parse error: ( ^ error: unclosed group - --> $DIR/regex.rs:21:41 + --> $DIR/regex.rs:26:41 | LL | let some_binary_regex = BRegex::new(OPENING_PAREN); | ^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ error: regex parse error: ( ^ error: unclosed group - --> $DIR/regex.rs:22:56 + --> $DIR/regex.rs:27:56 | LL | let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN); | ^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ error: regex parse error: ( ^ error: unclosed group - --> $DIR/regex.rs:34:37 + --> $DIR/regex.rs:39:37 | LL | let set_error = RegexSet::new(&[OPENING_PAREN, r"[a-z]+/.(com|org|net)"]); | ^^^^^^^^^^^^^ @@ -77,42 +77,72 @@ error: regex parse error: ( ^ error: unclosed group - --> $DIR/regex.rs:35:39 + --> $DIR/regex.rs:40:39 | LL | let bset_error = BRegexSet::new(&[OPENING_PAREN, r"[a-z]+/.(com|org|net)"]); | ^^^^^^^^^^^^^ -error: regex syntax error: unrecognized escape sequence - --> $DIR/regex.rs:37:45 - | -LL | let raw_string_error = Regex::new(r"[...//...]"); - | ^^ - -error: regex syntax error: unrecognized escape sequence - --> $DIR/regex.rs:38:46 - | -LL | let raw_string_error = Regex::new(r#"[...//...]"#); - | ^^ - error: regex parse error: /b/c ^^ error: unrecognized escape sequence - --> $DIR/regex.rs:40:42 - | -LL | let escaped_string_span = Regex::new("/b/c"); +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:47:42 +======= + --> $DIR/regex.rs:42:42 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:47:42 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) + | +LL | let escaped_string_span = Regex::new("//b//c"); | ^^^^^^^^ | = help: consider using a raw string literal: `r".."` error: regex syntax error: duplicate flag - --> $DIR/regex.rs:42:34 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:49:34 +======= + --> $DIR/regex.rs:44:34 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:49:34 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let aux_span = Regex::new("(?ixi)"); | ^ ^ +error: regex syntax error: pattern can match invalid UTF-8 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:54:53 +======= + --> $DIR/regex.rs:49:53 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:54:53 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) + | +LL | let invalid_utf8_should_lint = Regex::new("(?-u)."); + | ^ + error: trivial regex - --> $DIR/regex.rs:46:33 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:58:33 +======= + --> $DIR/regex.rs:48:33 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:53:33 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:58:33 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let trivial_eq = Regex::new("^foobar$"); | ^^^^^^^^^^ @@ -120,7 +150,19 @@ LL | let trivial_eq = Regex::new("^foobar$"); = help: consider using `==` on `str`s error: trivial regex - --> $DIR/regex.rs:48:48 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:60:48 +======= + --> $DIR/regex.rs:50:48 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:55:48 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:60:48 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let trivial_eq_builder = RegexBuilder::new("^foobar$"); | ^^^^^^^^^^ @@ -128,7 +170,19 @@ LL | let trivial_eq_builder = RegexBuilder::new("^foobar$"); = help: consider using `==` on `str`s error: trivial regex - --> $DIR/regex.rs:50:42 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:62:42 +======= + --> $DIR/regex.rs:52:42 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:57:42 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:62:42 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let trivial_starts_with = Regex::new("^foobar"); | ^^^^^^^^^ @@ -136,7 +190,19 @@ LL | let trivial_starts_with = Regex::new("^foobar"); = help: consider using `str::starts_with` error: trivial regex - --> $DIR/regex.rs:52:40 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:64:40 +======= + --> $DIR/regex.rs:54:40 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:59:40 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:64:40 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let trivial_ends_with = Regex::new("foobar$"); | ^^^^^^^^^ @@ -144,7 +210,19 @@ LL | let trivial_ends_with = Regex::new("foobar$"); = help: consider using `str::ends_with` error: trivial regex - --> $DIR/regex.rs:54:39 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:66:39 +======= + --> $DIR/regex.rs:56:39 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:61:39 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:66:39 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let trivial_contains = Regex::new("foobar"); | ^^^^^^^^ @@ -152,7 +230,19 @@ LL | let trivial_contains = Regex::new("foobar"); = help: consider using `str::contains` error: trivial regex - --> $DIR/regex.rs:56:39 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:68:39 +======= + --> $DIR/regex.rs:58:39 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:63:39 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:68:39 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let trivial_contains = Regex::new(NOT_A_REAL_REGEX); | ^^^^^^^^^^^^^^^^ @@ -160,15 +250,39 @@ LL | let trivial_contains = Regex::new(NOT_A_REAL_REGEX); = help: consider using `str::contains` error: trivial regex - --> $DIR/regex.rs:58:40 - | -LL | let trivial_backslash = Regex::new("a/.b"); +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:70:40 +======= + --> $DIR/regex.rs:60:40 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:65:40 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:70:40 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) + | +LL | let trivial_backslash = Regex::new("a//.b"); | ^^^^^^^ | = help: consider using `str::contains` error: trivial regex - --> $DIR/regex.rs:61:36 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:73:36 +======= + --> $DIR/regex.rs:63:36 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:68:36 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:73:36 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let trivial_empty = Regex::new(""); | ^^ @@ -176,7 +290,19 @@ LL | let trivial_empty = Regex::new(""); = help: the regex is unlikely to be useful as it is error: trivial regex - --> $DIR/regex.rs:63:36 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:75:36 +======= + --> $DIR/regex.rs:65:36 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:70:36 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:75:36 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let trivial_empty = Regex::new("^"); | ^^^ @@ -184,7 +310,19 @@ LL | let trivial_empty = Regex::new("^"); = help: the regex is unlikely to be useful as it is error: trivial regex - --> $DIR/regex.rs:65:36 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:77:36 +======= + --> $DIR/regex.rs:67:36 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:72:36 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:77:36 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let trivial_empty = Regex::new("^$"); | ^^^^ @@ -192,12 +330,32 @@ LL | let trivial_empty = Regex::new("^$"); = help: consider using `str::is_empty` error: trivial regex - --> $DIR/regex.rs:67:44 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/regex.rs:79:44 +======= + --> $DIR/regex.rs:69:44 +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= + --> $DIR/regex.rs:74:44 +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) +======= + --> $DIR/regex.rs:79:44 +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) | LL | let binary_trivial_empty = BRegex::new("^$"); | ^^^^ | = help: consider using `str::is_empty` -error: aborting due to 25 previous errors +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 24 previous errors +======= +error: aborting due to 23 previous errors +>>>>>>> 5fc1c7901 (bump up `regex-syntax` dependency version to 0.7.0) +======= +error: aborting due to 24 previous errors +>>>>>>> ffc2bc83b (Fixing `invalid_regex` with invalid UTF8. Also, adding more test cases) diff --git a/tests/ui/rename.fixed b/tests/ui/rename.fixed index 5076f61334d6..73a92f923a26 100644 --- a/tests/ui/rename.fixed +++ b/tests/ui/rename.fixed @@ -2,7 +2,7 @@ // Use that command to update this file and do not edit by hand. // Manual edits will be overwritten. -// run-rustfix +//@run-rustfix #![allow(clippy::almost_complete_range)] #![allow(clippy::disallowed_names)] @@ -16,6 +16,7 @@ #![allow(clippy::mixed_read_write_in_expression)] #![allow(clippy::useless_conversion)] #![allow(clippy::match_result_ok)] +#![allow(clippy::arithmetic_side_effects)] #![allow(clippy::overly_complex_bool_expr)] #![allow(clippy::new_without_default)] #![allow(clippy::bind_instead_of_map)] @@ -27,16 +28,30 @@ #![allow(clippy::module_name_repetitions)] #![allow(clippy::recursive_format_impl)] #![allow(clippy::invisible_characters)] +<<<<<<< HEAD +======= +#![allow(cast_ref_to_mut)] +#![allow(suspicious_double_ref_op)] +#![allow(invalid_nan_comparisons)] +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) #![allow(drop_bounds)] +#![allow(dropping_copy_types)] +#![allow(dropping_references)] #![allow(for_loops_over_fallibles)] +#![allow(forgetting_copy_types)] +#![allow(forgetting_references)] +#![allow(incorrect_fn_null_checks)] #![allow(array_into_iter)] #![allow(invalid_atomic_ordering)] #![allow(invalid_value)] +#![allow(invalid_from_utf8_unchecked)] #![allow(let_underscore_drop)] #![allow(enum_intrinsics_non_enums)] #![allow(non_fmt_panics)] #![allow(named_arguments_used_positionally)] +#![allow(suspicious_double_ref_op)] #![allow(temporary_cstring_as_ptr)] +#![allow(undropped_manually_drops)] #![allow(unknown_lints)] #![allow(unused_labels)] #![warn(clippy::almost_complete_range)] @@ -52,6 +67,7 @@ #![warn(clippy::mixed_read_write_in_expression)] #![warn(clippy::useless_conversion)] #![warn(clippy::match_result_ok)] +#![warn(clippy::arithmetic_side_effects)] #![warn(clippy::overly_complex_bool_expr)] #![warn(clippy::new_without_default)] #![warn(clippy::bind_instead_of_map)] @@ -67,18 +83,32 @@ #![warn(clippy::module_name_repetitions)] #![warn(clippy::recursive_format_impl)] #![warn(clippy::invisible_characters)] +<<<<<<< HEAD +#![warn(cast_ref_to_mut)] +#![warn(suspicious_double_ref_op)] +#![warn(invalid_nan_comparisons)] +======= +#![warn(suspicious_double_ref_op)] +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(drop_bounds)] +#![warn(dropping_copy_types)] +#![warn(dropping_references)] #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] +#![warn(forgetting_copy_types)] +#![warn(forgetting_references)] +#![warn(incorrect_fn_null_checks)] #![warn(array_into_iter)] #![warn(invalid_atomic_ordering)] #![warn(invalid_value)] +#![warn(invalid_from_utf8_unchecked)] #![warn(let_underscore_drop)] #![warn(enum_intrinsics_non_enums)] #![warn(non_fmt_panics)] #![warn(named_arguments_used_positionally)] #![warn(temporary_cstring_as_ptr)] +#![warn(undropped_manually_drops)] #![warn(unknown_lints)] #![warn(unused_labels)] diff --git a/tests/ui/rename.rs b/tests/ui/rename.rs index 64bc1ca7116c..b9d135e3b63b 100644 --- a/tests/ui/rename.rs +++ b/tests/ui/rename.rs @@ -2,7 +2,7 @@ // Use that command to update this file and do not edit by hand. // Manual edits will be overwritten. -// run-rustfix +//@run-rustfix #![allow(clippy::almost_complete_range)] #![allow(clippy::disallowed_names)] @@ -16,6 +16,7 @@ #![allow(clippy::mixed_read_write_in_expression)] #![allow(clippy::useless_conversion)] #![allow(clippy::match_result_ok)] +#![allow(clippy::arithmetic_side_effects)] #![allow(clippy::overly_complex_bool_expr)] #![allow(clippy::new_without_default)] #![allow(clippy::bind_instead_of_map)] @@ -27,16 +28,30 @@ #![allow(clippy::module_name_repetitions)] #![allow(clippy::recursive_format_impl)] #![allow(clippy::invisible_characters)] +<<<<<<< HEAD +======= +#![allow(cast_ref_to_mut)] +#![allow(suspicious_double_ref_op)] +#![allow(invalid_nan_comparisons)] +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) #![allow(drop_bounds)] +#![allow(dropping_copy_types)] +#![allow(dropping_references)] #![allow(for_loops_over_fallibles)] +#![allow(forgetting_copy_types)] +#![allow(forgetting_references)] +#![allow(incorrect_fn_null_checks)] #![allow(array_into_iter)] #![allow(invalid_atomic_ordering)] #![allow(invalid_value)] +#![allow(invalid_from_utf8_unchecked)] #![allow(let_underscore_drop)] #![allow(enum_intrinsics_non_enums)] #![allow(non_fmt_panics)] #![allow(named_arguments_used_positionally)] +#![allow(suspicious_double_ref_op)] #![allow(temporary_cstring_as_ptr)] +#![allow(undropped_manually_drops)] #![allow(unknown_lints)] #![allow(unused_labels)] #![warn(clippy::almost_complete_letter_range)] @@ -52,6 +67,7 @@ #![warn(clippy::eval_order_dependence)] #![warn(clippy::identity_conversion)] #![warn(clippy::if_let_some_result)] +#![warn(clippy::integer_arithmetic)] #![warn(clippy::logic_bug)] #![warn(clippy::new_without_default_derive)] #![warn(clippy::option_and_then_some)] @@ -67,18 +83,32 @@ #![warn(clippy::stutter)] #![warn(clippy::to_string_in_display)] #![warn(clippy::zero_width_space)] +<<<<<<< HEAD +#![warn(clippy::cast_ref_to_mut)] +#![warn(clippy::clone_double_ref)] +#![warn(clippy::cmp_nan)] +======= +#![warn(clippy::clone_double_ref)] +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::drop_bounds)] +#![warn(clippy::drop_copy)] +#![warn(clippy::drop_ref)] #![warn(clippy::for_loop_over_option)] #![warn(clippy::for_loop_over_result)] #![warn(clippy::for_loops_over_fallibles)] +#![warn(clippy::forget_copy)] +#![warn(clippy::forget_ref)] +#![warn(clippy::fn_null_check)] #![warn(clippy::into_iter_on_array)] #![warn(clippy::invalid_atomic_ordering)] #![warn(clippy::invalid_ref)] +#![warn(clippy::invalid_utf8_in_unchecked)] #![warn(clippy::let_underscore_drop)] #![warn(clippy::mem_discriminant_non_enum)] #![warn(clippy::panic_params)] #![warn(clippy::positional_named_format_parameters)] #![warn(clippy::temporary_cstring_as_ptr)] +#![warn(clippy::undropped_manually_drops)] #![warn(clippy::unknown_clippy_lints)] #![warn(clippy::unused_label)] diff --git a/tests/ui/rename.stderr b/tests/ui/rename.stderr index 27a0263292ef..ed662fe5a180 100644 --- a/tests/ui/rename.stderr +++ b/tests/ui/rename.stderr @@ -1,5 +1,13 @@ error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` - --> $DIR/rename.rs:42:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:53:9 +======= + --> $DIR/rename.rs:44:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:43:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` @@ -7,250 +15,666 @@ LL | #![warn(clippy::almost_complete_letter_range)] = note: `-D renamed-and-removed-lints` implied by `-D warnings` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` - --> $DIR/rename.rs:43:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:54:9 +======= + --> $DIR/rename.rs:45:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:44:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::blacklisted_name)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:44:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:55:9 +======= + --> $DIR/rename.rs:46:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:45:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:45:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:56:9 +======= + --> $DIR/rename.rs:47:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:46:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> $DIR/rename.rs:46:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:57:9 +======= + --> $DIR/rename.rs:48:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:47:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> $DIR/rename.rs:47:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:58:9 +======= + --> $DIR/rename.rs:49:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:48:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> $DIR/rename.rs:48:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:59:9 +======= + --> $DIR/rename.rs:50:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:49:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` - --> $DIR/rename.rs:49:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:60:9 +======= + --> $DIR/rename.rs:51:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:50:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::derive_hash_xor_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> $DIR/rename.rs:50:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:61:9 +======= + --> $DIR/rename.rs:52:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:51:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> $DIR/rename.rs:51:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:62:9 +======= + --> $DIR/rename.rs:53:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:52:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> $DIR/rename.rs:52:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:63:9 +======= + --> $DIR/rename.rs:54:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:53:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> $DIR/rename.rs:53:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:64:9 +======= + --> $DIR/rename.rs:55:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:54:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> $DIR/rename.rs:54:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:65:9 +======= + --> $DIR/rename.rs:56:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:55:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` +error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects` +<<<<<<< HEAD + --> $DIR/rename.rs:66:9 +======= + --> $DIR/rename.rs:57:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) + | +LL | #![warn(clippy::integer_arithmetic)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects` + error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> $DIR/rename.rs:55:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:67:9 +======= + --> $DIR/rename.rs:58:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:56:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> $DIR/rename.rs:56:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:68:9 +======= + --> $DIR/rename.rs:59:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:57:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> $DIR/rename.rs:57:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:69:9 +======= + --> $DIR/rename.rs:60:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:58:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:58:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:70:9 +======= + --> $DIR/rename.rs:61:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:59:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:59:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:71:9 +======= + --> $DIR/rename.rs:62:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:60:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:60:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:72:9 +======= + --> $DIR/rename.rs:63:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:61:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:61:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:73:9 +======= + --> $DIR/rename.rs:64:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:62:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> $DIR/rename.rs:62:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:74:9 +======= + --> $DIR/rename.rs:65:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:63:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:63:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:75:9 +======= + --> $DIR/rename.rs:66:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:64:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:64:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:76:9 +======= + --> $DIR/rename.rs:67:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:65:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:65:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:77:9 +======= + --> $DIR/rename.rs:68:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:66:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> $DIR/rename.rs:66:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:78:9 +======= + --> $DIR/rename.rs:69:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:67:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> $DIR/rename.rs:67:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:79:9 +======= + --> $DIR/rename.rs:70:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:68:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> $DIR/rename.rs:68:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:80:9 +======= + --> $DIR/rename.rs:71:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:69:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> $DIR/rename.rs:69:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:81:9 +======= + --> $DIR/rename.rs:72:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:70:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` +<<<<<<< HEAD +error: lint `clippy::cast_ref_to_mut` has been renamed to `cast_ref_to_mut` + --> $DIR/rename.rs:82:9 + | +LL | #![warn(clippy::cast_ref_to_mut)] + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `cast_ref_to_mut` + +error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` +<<<<<<< HEAD + --> $DIR/rename.rs:83:9 +======= + --> $DIR/rename.rs:73:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= +error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` + --> $DIR/rename.rs:71:9 +>>>>>>> e4f5d83fa (Fixed formatting.) + | +LL | #![warn(clippy::clone_double_ref)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op` + +<<<<<<< HEAD +error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons` + --> $DIR/rename.rs:84:9 + | +LL | #![warn(clippy::cmp_nan)] + | ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons` + error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> $DIR/rename.rs:70:9 +<<<<<<< HEAD + --> $DIR/rename.rs:85:9 +======= + --> $DIR/rename.rs:74:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= +error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` + --> $DIR/rename.rs:72:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` +error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types` + --> $DIR/rename.rs:86:9 + | +LL | #![warn(clippy::drop_copy)] + | ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types` + +error: lint `clippy::drop_ref` has been renamed to `dropping_references` + --> $DIR/rename.rs:87:9 + | +LL | #![warn(clippy::drop_ref)] + | ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references` + error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:71:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:88:9 +======= + --> $DIR/rename.rs:75:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:73:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:72:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:89:9 +======= + --> $DIR/rename.rs:76:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:74:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:73:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:90:9 +======= + --> $DIR/rename.rs:77:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:75:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` +error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types` + --> $DIR/rename.rs:91:9 + | +LL | #![warn(clippy::forget_copy)] + | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types` + +error: lint `clippy::forget_ref` has been renamed to `forgetting_references` + --> $DIR/rename.rs:92:9 + | +LL | #![warn(clippy::forget_ref)] + | ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references` + +error: lint `clippy::fn_null_check` has been renamed to `incorrect_fn_null_checks` + --> $DIR/rename.rs:93:9 + | +LL | #![warn(clippy::fn_null_check)] + | ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `incorrect_fn_null_checks` + error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> $DIR/rename.rs:74:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:94:9 +======= + --> $DIR/rename.rs:78:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:76:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> $DIR/rename.rs:75:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:95:9 +======= + --> $DIR/rename.rs:79:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:77:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> $DIR/rename.rs:76:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:96:9 +======= + --> $DIR/rename.rs:80:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:78:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` +error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked` + --> $DIR/rename.rs:97:9 + | +LL | #![warn(clippy::invalid_utf8_in_unchecked)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked` + error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> $DIR/rename.rs:77:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:98:9 +======= + --> $DIR/rename.rs:81:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:79:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> $DIR/rename.rs:78:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:99:9 +======= + --> $DIR/rename.rs:82:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:80:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> $DIR/rename.rs:79:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:100:9 +======= + --> $DIR/rename.rs:83:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:81:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> $DIR/rename.rs:80:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:101:9 +======= + --> $DIR/rename.rs:84:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:82:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` - --> $DIR/rename.rs:81:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:102:9 +======= + --> $DIR/rename.rs:85:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:83:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` +error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops` + --> $DIR/rename.rs:103:9 + | +LL | #![warn(clippy::undropped_manually_drops)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops` + error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> $DIR/rename.rs:82:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:104:9 +======= + --> $DIR/rename.rs:86:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:84:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> $DIR/rename.rs:83:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/rename.rs:105:9 +======= + --> $DIR/rename.rs:87:9 +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= + --> $DIR/rename.rs:85:9 +>>>>>>> e4f5d83fa (Fixed formatting.) | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` -error: aborting due to 42 previous errors +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 53 previous errors +======= +error: aborting due to 44 previous errors +>>>>>>> 493b2ae8d (Rename integer_arithmetic) +======= +error: aborting due to 43 previous errors +>>>>>>> e4f5d83fa (Fixed formatting.) diff --git a/tests/ui/renamed_builtin_attr.fixed b/tests/ui/renamed_builtin_attr.fixed index cb91b841d2cb..0334c1e1a29c 100644 --- a/tests/ui/renamed_builtin_attr.fixed +++ b/tests/ui/renamed_builtin_attr.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[clippy::cognitive_complexity = "1"] fn main() {} diff --git a/tests/ui/renamed_builtin_attr.rs b/tests/ui/renamed_builtin_attr.rs index b3ce2758067c..d350370c2449 100644 --- a/tests/ui/renamed_builtin_attr.rs +++ b/tests/ui/renamed_builtin_attr.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[clippy::cyclomatic_complexity = "1"] fn main() {} diff --git a/tests/ui/repeat_once.fixed b/tests/ui/repeat_once.fixed index dc197e50300d..c517bfcc6aa9 100644 --- a/tests/ui/repeat_once.fixed +++ b/tests/ui/repeat_once.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::repeat_once)] #[allow(unused, clippy::redundant_clone)] fn main() { diff --git a/tests/ui/repeat_once.rs b/tests/ui/repeat_once.rs index 0ec5127117c6..9a30b47418ff 100644 --- a/tests/ui/repeat_once.rs +++ b/tests/ui/repeat_once.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::repeat_once)] #[allow(unused, clippy::redundant_clone)] fn main() { diff --git a/tests/ui/result_map_or_into_option.fixed b/tests/ui/result_map_or_into_option.fixed index 331531b5165f..119ff25918a7 100644 --- a/tests/ui/result_map_or_into_option.fixed +++ b/tests/ui/result_map_or_into_option.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::result_map_or_into_option)] diff --git a/tests/ui/result_map_or_into_option.rs b/tests/ui/result_map_or_into_option.rs index 3058480e2ad3..eeeef830af0a 100644 --- a/tests/ui/result_map_or_into_option.rs +++ b/tests/ui/result_map_or_into_option.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::result_map_or_into_option)] diff --git a/tests/ui/result_map_unit_fn_fixable.fixed b/tests/ui/result_map_unit_fn_fixable.fixed index d8b56237e983..0583d29277b3 100644 --- a/tests/ui/result_map_unit_fn_fixable.fixed +++ b/tests/ui/result_map_unit_fn_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::result_map_unit_fn)] #![allow(unused)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/result_map_unit_fn_fixable.rs b/tests/ui/result_map_unit_fn_fixable.rs index 44f50d21109c..7ad3bdd04bd6 100644 --- a/tests/ui/result_map_unit_fn_fixable.rs +++ b/tests/ui/result_map_unit_fn_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::result_map_unit_fn)] #![allow(unused)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/result_map_unit_fn_fixable.stderr b/tests/ui/result_map_unit_fn_fixable.stderr index 782febd52644..ad941fa8bcc0 100644 --- a/tests/ui/result_map_unit_fn_fixable.stderr +++ b/tests/ui/result_map_unit_fn_fixable.stderr @@ -4,7 +4,7 @@ error: called `map(f)` on an `Result` value where `f` is a function that returns LL | x.field.map(do_nothing); | ^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(x_field) = x.field { do_nothing(x_field) }` + | help: try: `if let Ok(x_field) = x.field { do_nothing(x_field) }` | = note: `-D clippy::result-map-unit-fn` implied by `-D warnings` @@ -14,7 +14,7 @@ error: called `map(f)` on an `Result` value where `f` is a function that returns LL | x.field.map(do_nothing); | ^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(x_field) = x.field { do_nothing(x_field) }` + | help: try: `if let Ok(x_field) = x.field { do_nothing(x_field) }` error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:39:5 @@ -22,7 +22,7 @@ error: called `map(f)` on an `Result` value where `f` is a function that returns LL | x.field.map(diverge); | ^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(x_field) = x.field { diverge(x_field) }` + | help: try: `if let Ok(x_field) = x.field { diverge(x_field) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:45:5 @@ -30,7 +30,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| x.do_result_nothing(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { x.do_result_nothing(value + captured) }` + | help: try: `if let Ok(value) = x.field { x.do_result_nothing(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:47:5 @@ -38,7 +38,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { x.do_result_plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { x.do_result_plus_one(value + captured); }` + | help: try: `if let Ok(value) = x.field { x.do_result_plus_one(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:50:5 @@ -46,7 +46,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| do_nothing(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { do_nothing(value + captured) }` + | help: try: `if let Ok(value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:52:5 @@ -54,7 +54,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { do_nothing(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { do_nothing(value + captured) }` + | help: try: `if let Ok(value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:54:5 @@ -62,7 +62,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { do_nothing(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { do_nothing(value + captured); }` + | help: try: `if let Ok(value) = x.field { do_nothing(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:56:5 @@ -70,7 +70,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { { do_nothing(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { do_nothing(value + captured); }` + | help: try: `if let Ok(value) = x.field { do_nothing(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:59:5 @@ -78,7 +78,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| diverge(value + captured)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { diverge(value + captured) }` + | help: try: `if let Ok(value) = x.field { diverge(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:61:5 @@ -86,7 +86,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { diverge(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { diverge(value + captured) }` + | help: try: `if let Ok(value) = x.field { diverge(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:63:5 @@ -94,7 +94,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { diverge(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { diverge(value + captured); }` + | help: try: `if let Ok(value) = x.field { diverge(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:65:5 @@ -102,7 +102,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { { diverge(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { diverge(value + captured); }` + | help: try: `if let Ok(value) = x.field { diverge(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:70:5 @@ -110,7 +110,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { let y = plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { let y = plus_one(value + captured); }` + | help: try: `if let Ok(value) = x.field { let y = plus_one(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:72:5 @@ -118,7 +118,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { plus_one(value + captured); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { plus_one(value + captured); }` + | help: try: `if let Ok(value) = x.field { plus_one(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:74:5 @@ -126,7 +126,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { { plus_one(value + captured); } }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { plus_one(value + captured); }` + | help: try: `if let Ok(value) = x.field { plus_one(value + captured); }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:77:5 @@ -134,7 +134,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|ref value| { do_nothing(value + captured) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(ref value) = x.field { do_nothing(value + captured) }` + | help: try: `if let Ok(ref value) = x.field { do_nothing(value + captured) }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_fixable.rs:79:5 @@ -142,7 +142,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| println!("{:?}", value)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { println!("{:?}", value) }` + | help: try: `if let Ok(value) = x.field { println!("{:?}", value) }` error: aborting due to 18 previous errors diff --git a/tests/ui/result_map_unit_fn_unfixable.stderr b/tests/ui/result_map_unit_fn_unfixable.stderr index d0e534f63568..75ec1ba80245 100644 --- a/tests/ui/result_map_unit_fn_unfixable.stderr +++ b/tests/ui/result_map_unit_fn_unfixable.stderr @@ -4,7 +4,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { do_nothing(value); do_nothing(value) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { ... }` + | help: try: `if let Ok(value) = x.field { ... }` | = note: `-D clippy::result-map-unit-fn` implied by `-D warnings` @@ -14,7 +14,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { ... }` + | help: try: `if let Ok(value) = x.field { ... }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> $DIR/result_map_unit_fn_unfixable.rs:29:5 @@ -23,7 +23,7 @@ LL | // x.field.map(|value| { LL | || do_nothing(value); LL | || do_nothing(value) LL | || }); - | ||______^- help: try this: `if let Ok(value) = x.field { ... }` + | ||______^- help: try: `if let Ok(value) = x.field { ... }` | |______| | @@ -33,7 +33,7 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns LL | x.field.map(|value| { do_nothing(value); do_nothing(value); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(value) = x.field { ... }` + | help: try: `if let Ok(value) = x.field { ... }` error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()` --> $DIR/result_map_unit_fn_unfixable.rs:37:5 @@ -41,7 +41,7 @@ error: called `map(f)` on an `Result` value where `f` is a function that returns LL | "12".parse::().map(diverge); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(a) = "12".parse::() { diverge(a) }` + | help: try: `if let Ok(a) = "12".parse::() { diverge(a) }` error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()` --> $DIR/result_map_unit_fn_unfixable.rs:43:5 @@ -49,7 +49,7 @@ error: called `map(f)` on an `Result` value where `f` is a function that returns LL | y.map(do_nothing); | ^^^^^^^^^^^^^^^^^- | | - | help: try this: `if let Ok(_y) = y { do_nothing(_y) }` + | help: try: `if let Ok(_y) = y { do_nothing(_y) }` error: aborting due to 6 previous errors diff --git a/tests/ui/reversed_empty_ranges_fixable.fixed b/tests/ui/reversed_empty_ranges_fixable.fixed index c67edb36c67a..30dfc977681a 100644 --- a/tests/ui/reversed_empty_ranges_fixable.fixed +++ b/tests/ui/reversed_empty_ranges_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::reversed_empty_ranges)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/reversed_empty_ranges_fixable.rs b/tests/ui/reversed_empty_ranges_fixable.rs index 0a4fef5bfe87..1837249eae1e 100644 --- a/tests/ui/reversed_empty_ranges_fixable.rs +++ b/tests/ui/reversed_empty_ranges_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::reversed_empty_ranges)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/reversed_empty_ranges_loops_fixable.fixed b/tests/ui/reversed_empty_ranges_loops_fixable.fixed index 78401e463d50..a74569599c79 100644 --- a/tests/ui/reversed_empty_ranges_loops_fixable.fixed +++ b/tests/ui/reversed_empty_ranges_loops_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::reversed_empty_ranges)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/reversed_empty_ranges_loops_fixable.rs b/tests/ui/reversed_empty_ranges_loops_fixable.rs index f9e0f7fcd6db..42f9957dfbd0 100644 --- a/tests/ui/reversed_empty_ranges_loops_fixable.rs +++ b/tests/ui/reversed_empty_ranges_loops_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::reversed_empty_ranges)] #![allow(clippy::uninlined_format_args)] diff --git a/tests/ui/same_functions_in_if_condition.rs b/tests/ui/same_functions_in_if_condition.rs index e6198a1bc9a0..a207e4221355 100644 --- a/tests/ui/same_functions_in_if_condition.rs +++ b/tests/ui/same_functions_in_if_condition.rs @@ -1,5 +1,5 @@ #![feature(adt_const_params)] -#![warn(clippy::same_functions_in_if_condition)] +#![deny(clippy::same_functions_in_if_condition)] // ifs_same_cond warning is different from `ifs_same_cond`. // clippy::if_same_then_else, clippy::comparison_chain -- all empty blocks #![allow(incomplete_features)] @@ -10,6 +10,8 @@ clippy::uninlined_format_args )] +use std::marker::ConstParamTy; + fn function() -> bool { true } @@ -35,33 +37,33 @@ fn ifs_same_cond_fn() { if function() { } else if function() { - //~ ERROR ifs same condition + //~^ ERROR: `if` has the same function call as a previous `if` } if fn_arg(a) { } else if fn_arg(a) { - //~ ERROR ifs same condition + //~^ ERROR: `if` has the same function call as a previous `if` } if obj.method() { } else if obj.method() { - //~ ERROR ifs same condition + //~^ ERROR: `if` has the same function call as a previous `if` } if obj.method_arg(a) { } else if obj.method_arg(a) { - //~ ERROR ifs same condition + //~^ ERROR: `if` has the same function call as a previous `if` } let mut v = vec![1]; if v.pop().is_none() { - //~ ERROR ifs same condition } else if v.pop().is_none() { + //~^ ERROR: `if` has the same function call as a previous `if` } if v.len() == 42 { - //~ ERROR ifs same condition } else if v.len() == 42 { + //~^ ERROR: `if` has the same function call as a previous `if` } if v.len() == 1 { @@ -96,7 +98,7 @@ fn main() { }; println!("{}", os); - #[derive(PartialEq, Eq)] + #[derive(PartialEq, Eq, ConstParamTy)] enum E { A, B, diff --git a/tests/ui/same_functions_in_if_condition.stderr b/tests/ui/same_functions_in_if_condition.stderr index f352ade150ee..c23cd630f786 100644 --- a/tests/ui/same_functions_in_if_condition.stderr +++ b/tests/ui/same_functions_in_if_condition.stderr @@ -1,72 +1,84 @@ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:37:15 + --> $DIR/same_functions_in_if_condition.rs:39:15 | LL | } else if function() { | ^^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:36:8 + --> $DIR/same_functions_in_if_condition.rs:38:8 | LL | if function() { | ^^^^^^^^^^ - = note: `-D clippy::same-functions-in-if-condition` implied by `-D warnings` +note: the lint level is defined here + --> $DIR/same_functions_in_if_condition.rs:2:9 + | +LL | #![deny(clippy::same_functions_in_if_condition)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:42:15 + --> $DIR/same_functions_in_if_condition.rs:44:15 | LL | } else if fn_arg(a) { | ^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:41:8 + --> $DIR/same_functions_in_if_condition.rs:43:8 | LL | if fn_arg(a) { | ^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:47:15 + --> $DIR/same_functions_in_if_condition.rs:49:15 | LL | } else if obj.method() { | ^^^^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:46:8 + --> $DIR/same_functions_in_if_condition.rs:48:8 | LL | if obj.method() { | ^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:52:15 + --> $DIR/same_functions_in_if_condition.rs:54:15 | LL | } else if obj.method_arg(a) { | ^^^^^^^^^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:51:8 + --> $DIR/same_functions_in_if_condition.rs:53:8 | LL | if obj.method_arg(a) { | ^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:59:15 +<<<<<<< HEAD + --> $DIR/same_functions_in_if_condition.rs:60:15 +======= + --> $DIR/same_functions_in_if_condition.rs:58:15 +>>>>>>> 5bd97ac17 (Update tests) | LL | } else if v.pop().is_none() { | ^^^^^^^^^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:57:8 + --> $DIR/same_functions_in_if_condition.rs:59:8 | LL | if v.pop().is_none() { | ^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:64:15 +<<<<<<< HEAD + --> $DIR/same_functions_in_if_condition.rs:65:15 +======= + --> $DIR/same_functions_in_if_condition.rs:63:15 +>>>>>>> 5bd97ac17 (Update tests) | LL | } else if v.len() == 42 { | ^^^^^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:62:8 + --> $DIR/same_functions_in_if_condition.rs:64:8 | LL | if v.len() == 42 { | ^^^^^^^^^^^^^ diff --git a/tests/ui/same_name_method.rs b/tests/ui/same_name_method.rs index daef95a425c9..f31a7e33c4b9 100644 --- a/tests/ui/same_name_method.rs +++ b/tests/ui/same_name_method.rs @@ -62,7 +62,7 @@ mod should_lint { impl T1 for S {} } - mod multiply_conflicit_trait { + mod multiple_conflicting_traits { use crate::{T1, T2}; struct S; diff --git a/tests/ui/search_is_some.rs b/tests/ui/search_is_some.rs index 72f335153c1b..3cdbfaa16261 100644 --- a/tests/ui/search_is_some.rs +++ b/tests/ui/search_is_some.rs @@ -1,5 +1,6 @@ -// aux-build:option_helpers.rs +//@aux-build:option_helpers.rs #![warn(clippy::search_is_some)] +#![allow(clippy::useless_vec)] #![allow(dead_code)] extern crate option_helpers; use option_helpers::IteratorFalsePositives; diff --git a/tests/ui/search_is_some.stderr b/tests/ui/search_is_some.stderr index 6bea8c674779..7eff614d17c6 100644 --- a/tests/ui/search_is_some.stderr +++ b/tests/ui/search_is_some.stderr @@ -1,5 +1,5 @@ error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some.rs:14:13 + --> $DIR/search_is_some.rs:15:13 | LL | let _ = v.iter().find(|&x| { | _____________^ @@ -12,7 +12,7 @@ LL | | ).is_some(); = note: `-D clippy::search-is-some` implied by `-D warnings` error: called `is_some()` after searching an `Iterator` with `position` - --> $DIR/search_is_some.rs:20:13 + --> $DIR/search_is_some.rs:21:13 | LL | let _ = v.iter().position(|&x| { | _____________^ @@ -24,7 +24,7 @@ LL | | ).is_some(); = help: this is more succinctly expressed by calling `any()` error: called `is_some()` after searching an `Iterator` with `rposition` - --> $DIR/search_is_some.rs:26:13 + --> $DIR/search_is_some.rs:27:13 | LL | let _ = v.iter().rposition(|&x| { | _____________^ @@ -36,13 +36,13 @@ LL | | ).is_some(); = help: this is more succinctly expressed by calling `any()` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some.rs:41:20 + --> $DIR/search_is_some.rs:42:20 | LL | let _ = (0..1).find(some_closure).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(some_closure)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some.rs:51:13 + --> $DIR/search_is_some.rs:52:13 | LL | let _ = v.iter().find(|&x| { | _____________^ @@ -54,7 +54,7 @@ LL | | ).is_none(); = help: this is more succinctly expressed by calling `any()` with negation error: called `is_none()` after searching an `Iterator` with `position` - --> $DIR/search_is_some.rs:57:13 + --> $DIR/search_is_some.rs:58:13 | LL | let _ = v.iter().position(|&x| { | _____________^ @@ -66,7 +66,7 @@ LL | | ).is_none(); = help: this is more succinctly expressed by calling `any()` with negation error: called `is_none()` after searching an `Iterator` with `rposition` - --> $DIR/search_is_some.rs:63:13 + --> $DIR/search_is_some.rs:64:13 | LL | let _ = v.iter().rposition(|&x| { | _____________^ @@ -78,7 +78,7 @@ LL | | ).is_none(); = help: this is more succinctly expressed by calling `any()` with negation error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some.rs:78:13 + --> $DIR/search_is_some.rs:79:13 | LL | let _ = (0..1).find(some_closure).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(0..1).any(some_closure)` diff --git a/tests/ui/search_is_some_fixable_none.fixed b/tests/ui/search_is_some_fixable_none.fixed index 5190c5304c75..b245202f3b7f 100644 --- a/tests/ui/search_is_some_fixable_none.fixed +++ b/tests/ui/search_is_some_fixable_none.fixed @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +======= #![allow(dead_code, clippy::explicit_auto_deref)] +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::search_is_some)] fn main() { diff --git a/tests/ui/search_is_some_fixable_none.rs b/tests/ui/search_is_some_fixable_none.rs index 310d87333a93..80dec6623c69 100644 --- a/tests/ui/search_is_some_fixable_none.rs +++ b/tests/ui/search_is_some_fixable_none.rs @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +======= #![allow(dead_code, clippy::explicit_auto_deref)] +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::search_is_some)] fn main() { diff --git a/tests/ui/search_is_some_fixable_some.fixed b/tests/ui/search_is_some_fixable_some.fixed index 385a9986aba0..13599fe427af 100644 --- a/tests/ui/search_is_some_fixable_some.fixed +++ b/tests/ui/search_is_some_fixable_some.fixed @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +======= #![allow(dead_code, clippy::explicit_auto_deref)] +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::search_is_some)] fn main() { diff --git a/tests/ui/search_is_some_fixable_some.rs b/tests/ui/search_is_some_fixable_some.rs index 67e190ee3783..8c5d1d9d1c26 100644 --- a/tests/ui/search_is_some_fixable_some.rs +++ b/tests/ui/search_is_some_fixable_some.rs @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +======= #![allow(dead_code, clippy::explicit_auto_deref)] +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::search_is_some)] fn main() { diff --git a/tests/ui/seek_from_current.fixed b/tests/ui/seek_from_current.fixed index 1309c91b81c9..34c33baf686d 100644 --- a/tests/ui/seek_from_current.fixed +++ b/tests/ui/seek_from_current.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::seek_from_current)] use std::fs::File; diff --git a/tests/ui/seek_from_current.rs b/tests/ui/seek_from_current.rs index 5d9b1424cf68..22bcff1bc405 100644 --- a/tests/ui/seek_from_current.rs +++ b/tests/ui/seek_from_current.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::seek_from_current)] use std::fs::File; diff --git a/tests/ui/seek_to_start_instead_of_rewind.fixed b/tests/ui/seek_to_start_instead_of_rewind.fixed index dc24d447c607..d8a6e6985d4a 100644 --- a/tests/ui/seek_to_start_instead_of_rewind.fixed +++ b/tests/ui/seek_to_start_instead_of_rewind.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::seek_to_start_instead_of_rewind)] diff --git a/tests/ui/seek_to_start_instead_of_rewind.rs b/tests/ui/seek_to_start_instead_of_rewind.rs index 4adde2c40182..fc6a6433c2b0 100644 --- a/tests/ui/seek_to_start_instead_of_rewind.rs +++ b/tests/ui/seek_to_start_instead_of_rewind.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::seek_to_start_instead_of_rewind)] diff --git a/tests/ui/self_assignment.rs b/tests/ui/self_assignment.rs index ef6476229102..d6682cc63dcf 100644 --- a/tests/ui/self_assignment.rs +++ b/tests/ui/self_assignment.rs @@ -1,4 +1,5 @@ #![warn(clippy::self_assignment)] +#![allow(clippy::useless_vec, clippy::needless_pass_by_ref_mut)] pub struct S<'a> { a: i32, diff --git a/tests/ui/self_assignment.stderr b/tests/ui/self_assignment.stderr index 826e0d0ba888..bed88244eea7 100644 --- a/tests/ui/self_assignment.stderr +++ b/tests/ui/self_assignment.stderr @@ -1,5 +1,5 @@ error: self-assignment of `a` to `a` - --> $DIR/self_assignment.rs:12:5 + --> $DIR/self_assignment.rs:13:5 | LL | a = a; | ^^^^^ @@ -7,61 +7,61 @@ LL | a = a; = note: `-D clippy::self-assignment` implied by `-D warnings` error: self-assignment of `*b` to `*b` - --> $DIR/self_assignment.rs:13:5 + --> $DIR/self_assignment.rs:14:5 | LL | *b = *b; | ^^^^^^^ error: self-assignment of `s` to `s` - --> $DIR/self_assignment.rs:14:5 + --> $DIR/self_assignment.rs:15:5 | LL | s = s; | ^^^^^ error: self-assignment of `s.a` to `s.a` - --> $DIR/self_assignment.rs:15:5 + --> $DIR/self_assignment.rs:16:5 | LL | s.a = s.a; | ^^^^^^^^^ error: self-assignment of `s.b[5 + 5]` to `s.b[10]` - --> $DIR/self_assignment.rs:16:5 + --> $DIR/self_assignment.rs:17:5 | LL | s.b[10] = s.b[5 + 5]; | ^^^^^^^^^^^^^^^^^^^^ error: self-assignment of `s.c[0][1]` to `s.c[0][1]` - --> $DIR/self_assignment.rs:17:5 + --> $DIR/self_assignment.rs:18:5 | LL | s.c[0][1] = s.c[0][1]; | ^^^^^^^^^^^^^^^^^^^^^ error: self-assignment of `s.b[a]` to `s.b[a]` - --> $DIR/self_assignment.rs:18:5 + --> $DIR/self_assignment.rs:19:5 | LL | s.b[a] = s.b[a]; | ^^^^^^^^^^^^^^^ error: self-assignment of `*s.e` to `*s.e` - --> $DIR/self_assignment.rs:19:5 + --> $DIR/self_assignment.rs:20:5 | LL | *s.e = *s.e; | ^^^^^^^^^^^ error: self-assignment of `s.b[10 + a]` to `s.b[a + 10]` - --> $DIR/self_assignment.rs:20:5 + --> $DIR/self_assignment.rs:21:5 | LL | s.b[a + 10] = s.b[10 + a]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: self-assignment of `t.1` to `t.1` - --> $DIR/self_assignment.rs:23:5 + --> $DIR/self_assignment.rs:24:5 | LL | t.1 = t.1; | ^^^^^^^^^ error: self-assignment of `(t.0)` to `t.0` - --> $DIR/self_assignment.rs:24:5 + --> $DIR/self_assignment.rs:25:5 | LL | t.0 = (t.0); | ^^^^^^^^^^^ diff --git a/tests/ui/semicolon_inside_block.fixed b/tests/ui/semicolon_inside_block.fixed index 42e97e1ca358..ee359f60cbd7 100644 --- a/tests/ui/semicolon_inside_block.fixed +++ b/tests/ui/semicolon_inside_block.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/tests/ui/semicolon_inside_block.rs b/tests/ui/semicolon_inside_block.rs index f40848f702e1..e8516f79b20c 100644 --- a/tests/ui/semicolon_inside_block.rs +++ b/tests/ui/semicolon_inside_block.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/tests/ui/semicolon_outside_block.fixed b/tests/ui/semicolon_outside_block.fixed index 091eaa7518e9..034c7f8c7c18 100644 --- a/tests/ui/semicolon_outside_block.fixed +++ b/tests/ui/semicolon_outside_block.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/tests/ui/semicolon_outside_block.rs b/tests/ui/semicolon_outside_block.rs index 7ce46431fac9..4dc956d8a4b5 100644 --- a/tests/ui/semicolon_outside_block.rs +++ b/tests/ui/semicolon_outside_block.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/tests/ui/shadow.rs b/tests/ui/shadow.rs index 1fa9fc749a96..ef25e7fbac3b 100644 --- a/tests/ui/shadow.rs +++ b/tests/ui/shadow.rs @@ -1,6 +1,84 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs +======= +// aux-build:proc_macro_derive.rs +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +// aux-build:proc_macro_derive.rs +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +//@aux-build:proc_macro_derive.rs:proc-macro +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +//@aux-build:proc_macro_derive.rs:proc-macro +======= +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs +======= +// aux-build:proc_macro_derive.rs +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) + #![warn(clippy::shadow_same, clippy::shadow_reuse, clippy::shadow_unrelated)] -#![allow(clippy::let_unit_value)] +#![allow(clippy::let_unit_value, clippy::needless_if)] + +extern crate proc_macro_derive; + +#[derive(proc_macro_derive::ShadowDerive)] +pub struct Nothing; + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) +macro_rules! reuse { + ($v:ident) => { + let $v = $v + 1; + }; +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) +======= +extern crate proc_macro_derive; +#[derive(proc_macro_derive::ShadowDerive)] +pub struct Nothing; + +macro_rules! reuse { + ($v:ident) => { + let $v = $v + 1; + }; +} + +>>>>>>> 4da6e7e06 (rebase attempt) fn shadow_same() { let x = 1; let x = x; @@ -26,6 +104,12 @@ fn shadow_reuse() -> Option<()> { None } +fn shadow_reuse_macro() { + let x = 1; + // this should not warn + reuse!(x); +} + fn shadow_unrelated() { let x = 1; let x = 2; diff --git a/tests/ui/shadow.stderr b/tests/ui/shadow.stderr index c3d7bc2a5360..02ce6d99a9bd 100644 --- a/tests/ui/shadow.stderr +++ b/tests/ui/shadow.stderr @@ -1,278 +1,819 @@ error: `x` is shadowed by itself in `x` - --> $DIR/shadow.rs:6:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:19:9 +======= + --> $DIR/shadow.rs:13:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:13:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:19:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:5:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:18:9 +======= + --> $DIR/shadow.rs:12:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:12:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:18:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = 1; | ^ = note: `-D clippy::shadow-same` implied by `-D warnings` error: `mut x` is shadowed by itself in `&x` - --> $DIR/shadow.rs:7:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:20:13 +======= + --> $DIR/shadow.rs:14:13 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:14:13 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:20:13 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let mut x = &x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:6:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:19:9 +======= + --> $DIR/shadow.rs:13:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:13:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:19:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = x; | ^ error: `x` is shadowed by itself in `&mut x` - --> $DIR/shadow.rs:8:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:21:9 +======= + --> $DIR/shadow.rs:15:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:15:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:21:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = &mut x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:7:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:20:9 +======= + --> $DIR/shadow.rs:14:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:14:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:20:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let mut x = &x; | ^^^^^ error: `x` is shadowed by itself in `*x` - --> $DIR/shadow.rs:9:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:22:9 +======= + --> $DIR/shadow.rs:16:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:16:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:22:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = *x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:8:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:21:9 +======= + --> $DIR/shadow.rs:15:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:15:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:21:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = &mut x; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:14:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:27:9 +======= + --> $DIR/shadow.rs:21:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:21:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:27:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = x.0; | ^ | note: previous binding is here - --> $DIR/shadow.rs:13:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:26:9 +======= + --> $DIR/shadow.rs:20:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:20:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:26:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = ([[0]], ()); | ^ = note: `-D clippy::shadow-reuse` implied by `-D warnings` error: `x` is shadowed - --> $DIR/shadow.rs:15:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) + --> $DIR/shadow.rs:28:9 | LL | let x = x[0]; | ^ | note: previous binding is here - --> $DIR/shadow.rs:14:9 + --> $DIR/shadow.rs:27:9 +<<<<<<< HEAD | LL | let x = x.0; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:16:10 + --> $DIR/shadow.rs:29:10 | LL | let [x] = x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:15:9 + --> $DIR/shadow.rs:28:9 | LL | let x = x[0]; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:17:9 + --> $DIR/shadow.rs:30:9 | LL | let x = Some(x); | ^ | note: previous binding is here - --> $DIR/shadow.rs:16:10 + --> $DIR/shadow.rs:29:10 | LL | let [x] = x; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:18:9 + --> $DIR/shadow.rs:31:9 | LL | let x = foo(x); | ^ | note: previous binding is here - --> $DIR/shadow.rs:17:9 + --> $DIR/shadow.rs:30:9 | LL | let x = Some(x); | ^ error: `x` is shadowed - --> $DIR/shadow.rs:19:9 + --> $DIR/shadow.rs:32:9 | LL | let x = || x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:18:9 + --> $DIR/shadow.rs:31:9 | LL | let x = foo(x); | ^ error: `x` is shadowed - --> $DIR/shadow.rs:20:9 + --> $DIR/shadow.rs:33:9 | LL | let x = Some(1).map(|_| x)?; | ^ | note: previous binding is here - --> $DIR/shadow.rs:19:9 + --> $DIR/shadow.rs:32:9 | LL | let x = || x; | ^ error: `y` is shadowed + --> $DIR/shadow.rs:35:9 +======= +======= +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) + --> $DIR/shadow.rs:22:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) + | +LL | let x = x[0]; + | ^ + | +note: previous binding is here + --> $DIR/shadow.rs:34:9 + | +LL | let x = x.0; + | ^ + +error: `x` is shadowed + --> $DIR/shadow.rs:23:10 + | +LL | let [x] = x; + | ^ + | +note: previous binding is here --> $DIR/shadow.rs:22:9 | +LL | let x = x[0]; + | ^ + +error: `x` is shadowed + --> $DIR/shadow.rs:24:9 + | +LL | let x = Some(x); + | ^ + | +note: previous binding is here + --> $DIR/shadow.rs:23:10 + | +LL | let [x] = x; + | ^ + +error: `x` is shadowed + --> $DIR/shadow.rs:25:9 + | +LL | let x = foo(x); + | ^ + | +note: previous binding is here + --> $DIR/shadow.rs:24:9 + | +LL | let x = Some(x); + | ^ + +error: `x` is shadowed + --> $DIR/shadow.rs:26:9 + | +LL | let x = || x; + | ^ + | +note: previous binding is here + --> $DIR/shadow.rs:25:9 + | +LL | let x = foo(x); + | ^ + +error: `x` is shadowed + --> $DIR/shadow.rs:27:9 + | +LL | let x = Some(1).map(|_| x)?; + | ^ + | +note: previous binding is here + --> $DIR/shadow.rs:26:9 + | +LL | let x = || x; + | ^ + +error: `y` is shadowed + --> $DIR/shadow.rs:29:9 + | +LL | let x = x[0]; + | ^ + | +note: previous binding is here + --> $DIR/shadow.rs:28:9 +======= +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) + | +LL | let x = x.0; + | ^ + +error: `x` is shadowed + --> $DIR/shadow.rs:29:10 + | +LL | let [x] = x; + | ^ + | +note: previous binding is here + --> $DIR/shadow.rs:28:9 + | +LL | let x = x[0]; + | ^ + +error: `x` is shadowed + --> $DIR/shadow.rs:30:9 + | +LL | let x = Some(x); + | ^ + | +note: previous binding is here + --> $DIR/shadow.rs:29:10 + | +LL | let [x] = x; + | ^ + +error: `x` is shadowed + --> $DIR/shadow.rs:31:9 + | +LL | let x = foo(x); + | ^ + | +note: previous binding is here + --> $DIR/shadow.rs:30:9 + | +LL | let x = Some(x); + | ^ + +error: `x` is shadowed + --> $DIR/shadow.rs:32:9 + | +LL | let x = || x; + | ^ + | +note: previous binding is here + --> $DIR/shadow.rs:31:9 + | +LL | let x = foo(x); + | ^ + +error: `x` is shadowed + --> $DIR/shadow.rs:33:9 + | +LL | let x = Some(1).map(|_| x)?; + | ^ + | +note: previous binding is here + --> $DIR/shadow.rs:32:9 + | +LL | let x = || x; + | ^ + +error: `y` is shadowed + --> $DIR/shadow.rs:35:9 + | LL | let y = match y { | ^ | note: previous binding is here - --> $DIR/shadow.rs:21:9 + --> $DIR/shadow.rs:34:9 | LL | let y = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:31:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:50:9 +======= + --> $DIR/shadow.rs:38:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:38:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:50:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = 2; | ^ | note: previous binding is here - --> $DIR/shadow.rs:30:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:49:9 +======= + --> $DIR/shadow.rs:37:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:37:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:49:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = 1; | ^ = note: `-D clippy::shadow-unrelated` implied by `-D warnings` error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:36:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:55:13 +======= + --> $DIR/shadow.rs:43:13 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:43:13 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:55:13 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = 1; | ^ | note: previous binding is here - --> $DIR/shadow.rs:35:10 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:54:10 +======= + --> $DIR/shadow.rs:42:10 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:42:10 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:54:10 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | fn f(x: u32) { | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:41:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:60:14 +======= + --> $DIR/shadow.rs:48:14 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:48:14 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:60:14 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | Some(x) => { | ^ | note: previous binding is here - --> $DIR/shadow.rs:38:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:57:9 +======= + --> $DIR/shadow.rs:45:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:45:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:57:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:42:17 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:61:17 +======= + --> $DIR/shadow.rs:49:17 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:49:17 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:61:17 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = 1; | ^ | note: previous binding is here - --> $DIR/shadow.rs:41:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:60:14 +======= + --> $DIR/shadow.rs:48:14 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:48:14 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:60:14 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | Some(x) => { | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:46:17 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:65:17 +======= + --> $DIR/shadow.rs:53:17 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:53:17 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:65:17 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | if let Some(x) = Some(1) {} | ^ | note: previous binding is here - --> $DIR/shadow.rs:38:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:57:9 +======= + --> $DIR/shadow.rs:45:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:45:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:57:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:47:20 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:66:20 +======= + --> $DIR/shadow.rs:54:20 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:54:20 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:66:20 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | while let Some(x) = Some(1) {} | ^ | note: previous binding is here - --> $DIR/shadow.rs:38:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:57:9 +======= + --> $DIR/shadow.rs:45:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:45:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:57:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:48:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:67:15 +======= + --> $DIR/shadow.rs:55:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:55:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:67:15 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let _ = |[x]: [u32; 1]| { | ^ | note: previous binding is here - --> $DIR/shadow.rs:38:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:57:9 +======= + --> $DIR/shadow.rs:45:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:45:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:57:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:49:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:68:13 +======= + --> $DIR/shadow.rs:56:13 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:56:13 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:68:13 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = 1; | ^ | note: previous binding is here - --> $DIR/shadow.rs:48:15 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:67:15 +======= + --> $DIR/shadow.rs:55:15 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:55:15 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:67:15 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let _ = |[x]: [u32; 1]| { | ^ error: `y` is shadowed - --> $DIR/shadow.rs:52:17 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:71:17 +======= + --> $DIR/shadow.rs:59:17 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:59:17 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:71:17 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | if let Some(y) = y {} | ^ | note: previous binding is here - --> $DIR/shadow.rs:51:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:70:9 +======= + --> $DIR/shadow.rs:58:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:58:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:70:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let y = Some(1); | ^ error: `_b` shadows a previous, unrelated binding - --> $DIR/shadow.rs:88:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:107:9 +======= + --> $DIR/shadow.rs:95:9 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:95:9 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:107:9 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let _b = _a; | ^^ | note: previous binding is here - --> $DIR/shadow.rs:87:28 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:106:28 +======= + --> $DIR/shadow.rs:94:28 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:94:28 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:106:28 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | pub async fn foo2(_a: i32, _b: i64) { | ^^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:94:21 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:113:21 +======= + --> $DIR/shadow.rs:101:21 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:101:21 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:113:21 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | if let Some(x) = Some(1) { x } else { 1 } | ^ | note: previous binding is here - --> $DIR/shadow.rs:93:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/shadow.rs:112:13 +======= + --> $DIR/shadow.rs:100:13 +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= + --> $DIR/shadow.rs:100:13 +>>>>>>> cd0009eb3 (Suppress the triggering of some lints in derived structures) +======= + --> $DIR/shadow.rs:112:13 +>>>>>>> 628605e07 (Ignore `shadow` warns in code from macro expansions) | LL | let x = 1; | ^ diff --git a/tests/ui/short_circuit_statement.fixed b/tests/ui/short_circuit_statement.fixed index dd22ecab0b55..1737d5014419 100644 --- a/tests/ui/short_circuit_statement.fixed +++ b/tests/ui/short_circuit_statement.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::short_circuit_statement)] #![allow(clippy::nonminimal_bool)] diff --git a/tests/ui/short_circuit_statement.rs b/tests/ui/short_circuit_statement.rs index 73a55bf1f5e2..ab93aa1ca5ca 100644 --- a/tests/ui/short_circuit_statement.rs +++ b/tests/ui/short_circuit_statement.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::short_circuit_statement)] #![allow(clippy::nonminimal_bool)] diff --git a/tests/ui/should_impl_trait/method_list_2.stderr b/tests/ui/should_impl_trait/method_list_2.stderr index 10bfea68ff57..2ae9fa34d142 100644 --- a/tests/ui/should_impl_trait/method_list_2.stderr +++ b/tests/ui/should_impl_trait/method_list_2.stderr @@ -39,6 +39,15 @@ LL | | } | = help: consider implementing the trait `std::hash::Hash` or choosing a less ambiguous method name +error: this argument is a mutable reference, but not used mutably + --> $DIR/method_list_2.rs:38:31 + | +LL | pub fn hash(&self, state: &mut T) { + | ^^^^^^ help: consider changing to: `&T` + | + = warning: changing this function will impact semver compatibility + = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` + error: method `index` can be confused for the standard trait method `std::ops::Index::index` --> $DIR/method_list_2.rs:42:5 | @@ -149,5 +158,5 @@ LL | | } | = help: consider implementing the trait `std::ops::Sub` or choosing a less ambiguous method name -error: aborting due to 15 previous errors +error: aborting due to 16 previous errors diff --git a/tests/ui/significant_drop_in_scrutinee.fixed b/tests/ui/significant_drop_in_scrutinee.fixed new file mode 100644 index 000000000000..acc78d6bb043 --- /dev/null +++ b/tests/ui/significant_drop_in_scrutinee.fixed @@ -0,0 +1,627 @@ +// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934 +// //@run-rustfix +#![warn(clippy::significant_drop_in_scrutinee)] +#![allow(dead_code, unused_assignments)] +#![allow(clippy::match_single_binding, clippy::single_match, clippy::uninlined_format_args)] + +use std::num::ParseIntError; +use std::ops::Deref; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::RwLock; +use std::sync::{Mutex, MutexGuard}; + +struct State {} + +impl State { + fn foo(&self) -> bool { + true + } + + fn bar(&self) {} +} + +fn should_not_trigger_lint_with_mutex_guard_outside_match() { + let mutex = Mutex::new(State {}); + + // Should not trigger lint because the temporary should drop at the `;` on line before the match + let is_foo = mutex.lock().unwrap().foo(); + match is_foo { + true => { + mutex.lock().unwrap().bar(); + }, + false => {}, + }; +} + +fn should_not_trigger_lint_with_mutex_guard_when_taking_ownership_in_match() { + let mutex = Mutex::new(State {}); + + // Should not trigger lint because the scrutinee is explicitly returning the MutexGuard, + // so its lifetime should not be surprising. + match mutex.lock() { + Ok(guard) => { + guard.foo(); + mutex.lock().unwrap().bar(); + }, + _ => {}, + }; +} + +fn should_trigger_lint_with_mutex_guard_in_match_scrutinee() { + let mutex = Mutex::new(State {}); + + // Should trigger lint because the lifetime of the temporary MutexGuard is surprising because it + // is preserved until the end of the match, but there is no clear indication that this is the + // case. + match mutex.lock().unwrap().foo() { + true => { + mutex.lock().unwrap().bar(); + }, + false => {}, + }; +} + +fn should_not_trigger_lint_with_mutex_guard_in_match_scrutinee_when_lint_allowed() { + let mutex = Mutex::new(State {}); + + // Lint should not be triggered because it is "allowed" below. + #[allow(clippy::significant_drop_in_scrutinee)] + match mutex.lock().unwrap().foo() { + true => { + mutex.lock().unwrap().bar(); + }, + false => {}, + }; +} + +fn should_not_trigger_lint_for_insignificant_drop() { + // Should not trigger lint because there are no temporaries whose drops have a significant + // side effect. + match 1u64.to_string().is_empty() { + true => { + println!("It was empty") + }, + false => { + println!("It was not empty") + }, + } +} + +struct StateWithMutex { + m: Mutex, +} + +struct MutexGuardWrapper<'a> { + mg: MutexGuard<'a, u64>, +} + +impl<'a> MutexGuardWrapper<'a> { + fn get_the_value(&self) -> u64 { + *self.mg.deref() + } +} + +struct MutexGuardWrapperWrapper<'a> { + mg: MutexGuardWrapper<'a>, +} + +impl<'a> MutexGuardWrapperWrapper<'a> { + fn get_the_value(&self) -> u64 { + *self.mg.mg.deref() + } +} + +impl StateWithMutex { + fn lock_m(&self) -> MutexGuardWrapper<'_> { + MutexGuardWrapper { + mg: self.m.lock().unwrap(), + } + } + + fn lock_m_m(&self) -> MutexGuardWrapperWrapper<'_> { + MutexGuardWrapperWrapper { + mg: MutexGuardWrapper { + mg: self.m.lock().unwrap(), + }, + } + } + + fn foo(&self) -> bool { + true + } + + fn bar(&self) {} +} + +fn should_trigger_lint_with_wrapped_mutex() { + let s = StateWithMutex { m: Mutex::new(1) }; + + // Should trigger lint because a temporary contains a type with a significant drop and its + // lifetime is not obvious. Additionally, it is not obvious from looking at the scrutinee that + // the temporary contains such a type, making it potentially even more surprising. + match s.lock_m().get_the_value() { + 1 => { + println!("Got 1. Is it still 1?"); + println!("{}", s.lock_m().get_the_value()); + }, + 2 => { + println!("Got 2. Is it still 2?"); + println!("{}", s.lock_m().get_the_value()); + }, + _ => {}, + } + println!("All done!"); +} + +fn should_trigger_lint_with_double_wrapped_mutex() { + let s = StateWithMutex { m: Mutex::new(1) }; + + // Should trigger lint because a temporary contains a type which further contains a type with a + // significant drop and its lifetime is not obvious. Additionally, it is not obvious from + // looking at the scrutinee that the temporary contains such a type, making it potentially even + // more surprising. + match s.lock_m_m().get_the_value() { + 1 => { + println!("Got 1. Is it still 1?"); + println!("{}", s.lock_m().get_the_value()); + }, + 2 => { + println!("Got 2. Is it still 2?"); + println!("{}", s.lock_m().get_the_value()); + }, + _ => {}, + } + println!("All done!"); +} + +struct Counter { + i: AtomicU64, +} + +#[clippy::has_significant_drop] +struct CounterWrapper<'a> { + counter: &'a Counter, +} + +impl<'a> CounterWrapper<'a> { + fn new(counter: &Counter) -> CounterWrapper { + counter.i.fetch_add(1, Ordering::Relaxed); + CounterWrapper { counter } + } +} + +impl<'a> Drop for CounterWrapper<'a> { + fn drop(&mut self) { + self.counter.i.fetch_sub(1, Ordering::Relaxed); + } +} + +impl Counter { + fn temp_increment(&self) -> Vec { + vec![CounterWrapper::new(self), CounterWrapper::new(self)] + } +} + +fn should_trigger_lint_for_vec() { + let counter = Counter { i: AtomicU64::new(0) }; + + // Should trigger lint because the temporary in the scrutinee returns a collection of types + // which have significant drops. The types with significant drops are also non-obvious when + // reading the expression in the scrutinee. + match counter.temp_increment().len() { + 2 => { + let current_count = counter.i.load(Ordering::Relaxed); + println!("Current count {}", current_count); + assert_eq!(current_count, 0); + }, + 1 => {}, + 3 => {}, + _ => {}, + }; +} + +struct StateWithField { + s: String, +} + +// Should trigger lint only on the type in the tuple which is created using a temporary +// with a significant drop. Additionally, this test ensures that the format of the tuple +// is preserved correctly in the suggestion. +fn should_trigger_lint_for_tuple_in_scrutinee() { + let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() }); + + { + match (mutex1.lock().unwrap().s.len(), true) { + (3, _) => { + println!("started"); + mutex1.lock().unwrap().s.len(); + println!("done"); + }, + (_, _) => {}, + }; + + match (true, mutex1.lock().unwrap().s.len(), true) { + (_, 3, _) => { + println!("started"); + mutex1.lock().unwrap().s.len(); + println!("done"); + }, + (_, _, _) => {}, + }; + + let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() }); + match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) { + (3, _, 3) => { + println!("started"); + mutex1.lock().unwrap().s.len(); + mutex2.lock().unwrap().s.len(); + println!("done"); + }, + (_, _, _) => {}, + }; + + let mutex3 = Mutex::new(StateWithField { s: "three".to_owned() }); + match mutex3.lock().unwrap().s.as_str() { + "three" => { + println!("started"); + mutex1.lock().unwrap().s.len(); + mutex2.lock().unwrap().s.len(); + println!("done"); + }, + _ => {}, + }; + + match (true, mutex3.lock().unwrap().s.as_str()) { + (_, "three") => { + println!("started"); + mutex1.lock().unwrap().s.len(); + mutex2.lock().unwrap().s.len(); + println!("done"); + }, + (_, _) => {}, + }; + } +} + +// Should trigger lint when either side of a binary operation creates a temporary with a +// significant drop. +// To avoid potential unnecessary copies or creating references that would trigger the significant +// drop problem, the lint recommends moving the entire binary operation. +fn should_trigger_lint_for_accessing_field_in_mutex_in_one_side_of_binary_op() { + let mutex = Mutex::new(StateWithField { s: "state".to_owned() }); + + match mutex.lock().unwrap().s.len() > 1 { + true => { + mutex.lock().unwrap().s.len(); + }, + false => {}, + }; + + match 1 < mutex.lock().unwrap().s.len() { + true => { + mutex.lock().unwrap().s.len(); + }, + false => {}, + }; +} + +// Should trigger lint when both sides of a binary operation creates a temporary with a +// significant drop. +// To avoid potential unnecessary copies or creating references that would trigger the significant +// drop problem, the lint recommends moving the entire binary operation. +fn should_trigger_lint_for_accessing_fields_in_mutex_in_both_sides_of_binary_op() { + let mutex1 = Mutex::new(StateWithField { s: "state".to_owned() }); + let mutex2 = Mutex::new(StateWithField { + s: "statewithfield".to_owned(), + }); + + match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() { + true => { + println!( + "{} < {}", + mutex1.lock().unwrap().s.len(), + mutex2.lock().unwrap().s.len() + ); + }, + false => {}, + }; + + match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() { + true => { + println!( + "{} >= {}", + mutex1.lock().unwrap().s.len(), + mutex2.lock().unwrap().s.len() + ); + }, + false => {}, + }; +} + +fn should_not_trigger_lint_for_closure_in_scrutinee() { + let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() }); + + let get_mutex_guard = || mutex1.lock().unwrap().s.len(); + + // Should not trigger lint because the temporary with a significant drop will be dropped + // at the end of the closure, so the MutexGuard will be unlocked and not have a potentially + // surprising lifetime. + match get_mutex_guard() > 1 { + true => { + mutex1.lock().unwrap().s.len(); + }, + false => {}, + }; +} + +fn should_trigger_lint_for_return_from_closure_in_scrutinee() { + let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() }); + + let get_mutex_guard = || mutex1.lock().unwrap(); + + // Should trigger lint because the temporary with a significant drop is returned from the + // closure but not used directly in any match arms, so it has a potentially surprising lifetime. + match get_mutex_guard().s.len() > 1 { + true => { + mutex1.lock().unwrap().s.len(); + }, + false => {}, + }; +} + +fn should_trigger_lint_for_return_from_match_in_scrutinee() { + let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() }); + let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() }); + + let i = 100; + + // Should trigger lint because the nested match within the scrutinee returns a temporary with a + // significant drop is but not used directly in any match arms, so it has a potentially + // surprising lifetime. + match match i { + 100 => mutex1.lock().unwrap(), + _ => mutex2.lock().unwrap(), + } + .s + .len() + > 1 + { + true => { + mutex1.lock().unwrap().s.len(); + }, + false => { + println!("nothing to do here"); + }, + }; +} + +fn should_trigger_lint_for_return_from_if_in_scrutinee() { + let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() }); + let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() }); + + let i = 100; + + // Should trigger lint because the nested if-expression within the scrutinee returns a temporary + // with a significant drop is but not used directly in any match arms, so it has a potentially + // surprising lifetime. + match if i > 1 { + mutex1.lock().unwrap() + } else { + mutex2.lock().unwrap() + } + .s + .len() + > 1 + { + true => { + mutex1.lock().unwrap().s.len(); + }, + false => {}, + }; +} + +fn should_not_trigger_lint_for_if_in_scrutinee() { + let mutex = Mutex::new(StateWithField { s: "state".to_owned() }); + + let i = 100; + + // Should not trigger the lint because the temporary with a significant drop *is* dropped within + // the body of the if-expression nested within the match scrutinee, and therefore does not have + // a potentially surprising lifetime. + match if i > 1 { + mutex.lock().unwrap().s.len() > 1 + } else { + false + } { + true => { + mutex.lock().unwrap().s.len(); + }, + false => {}, + }; +} + +struct StateWithBoxedMutexGuard { + u: Mutex, +} + +impl StateWithBoxedMutexGuard { + fn new() -> StateWithBoxedMutexGuard { + StateWithBoxedMutexGuard { u: Mutex::new(42) } + } + fn lock(&self) -> Box> { + Box::new(self.u.lock().unwrap()) + } +} + +fn should_trigger_lint_for_boxed_mutex_guard() { + let s = StateWithBoxedMutexGuard::new(); + + // Should trigger lint because a temporary Box holding a type with a significant drop in a match + // scrutinee may have a potentially surprising lifetime. + match s.lock().deref().deref() { + 0 | 1 => println!("Value was less than 2"), + _ => println!("Value is {}", s.lock().deref()), + }; +} + +struct StateStringWithBoxedMutexGuard { + s: Mutex, +} + +impl StateStringWithBoxedMutexGuard { + fn new() -> StateStringWithBoxedMutexGuard { + StateStringWithBoxedMutexGuard { + s: Mutex::new("A String".to_owned()), + } + } + fn lock(&self) -> Box> { + Box::new(self.s.lock().unwrap()) + } +} + +fn should_trigger_lint_for_boxed_mutex_guard_holding_string() { + let s = StateStringWithBoxedMutexGuard::new(); + + let matcher = String::from("A String"); + + // Should trigger lint because a temporary Box holding a type with a significant drop in a match + // scrutinee may have a potentially surprising lifetime. + match s.lock().deref().deref() { + matcher => println!("Value is {}", s.lock().deref()), + _ => println!("Value was not a match"), + }; +} + +struct StateWithIntField { + i: u64, +} + +// Should trigger lint when either side of an assign expression contains a temporary with a +// significant drop, because the temporary's lifetime will be extended to the end of the match. +// To avoid potential unnecessary copies or creating references that would trigger the significant +// drop problem, the lint recommends moving the entire binary operation. +fn should_trigger_lint_in_assign_expr() { + let mutex = Mutex::new(StateWithIntField { i: 10 }); + + let mut i = 100; + + match mutex.lock().unwrap().i = i { + _ => { + println!("{}", mutex.lock().unwrap().i); + }, + }; + + match i = mutex.lock().unwrap().i { + _ => { + println!("{}", mutex.lock().unwrap().i); + }, + }; + + match mutex.lock().unwrap().i += 1 { + _ => { + println!("{}", mutex.lock().unwrap().i); + }, + }; + + match i += mutex.lock().unwrap().i { + _ => { + println!("{}", mutex.lock().unwrap().i); + }, + }; +} + +#[derive(Debug)] +enum RecursiveEnum { + Foo(Option>), +} + +#[derive(Debug)] +enum GenericRecursiveEnum { + Foo(T, Option>>), +} + +fn should_not_cause_stack_overflow() { + // Test that when a type recursively contains itself, a stack overflow does not occur when + // checking sub-types for significant drops. + let f = RecursiveEnum::Foo(Some(Box::new(RecursiveEnum::Foo(None)))); + match f { + RecursiveEnum::Foo(Some(f)) => { + println!("{:?}", f) + }, + RecursiveEnum::Foo(f) => { + println!("{:?}", f) + }, + } + + let f = GenericRecursiveEnum::Foo(1u64, Some(Box::new(GenericRecursiveEnum::Foo(2u64, None)))); + match f { + GenericRecursiveEnum::Foo(i, Some(f)) => { + println!("{} {:?}", i, f) + }, + GenericRecursiveEnum::Foo(i, f) => { + println!("{} {:?}", i, f) + }, + } +} + +fn should_not_produce_lint_for_try_desugar() -> Result { + // TryDesugar (i.e. using `?` for a Result type) will turn into a match but is out of scope + // for this lint + let rwlock = RwLock::new("1".to_string()); + let result = rwlock.read().unwrap().parse::()?; + println!("{}", result); + rwlock.write().unwrap().push('2'); + Ok(result) +} + +struct ResultReturner { + s: String, +} + +impl ResultReturner { + fn to_number(&self) -> Result { + self.s.parse::() + } +} + +fn should_trigger_lint_for_non_ref_move_and_clone_suggestion() { + let rwlock = RwLock::::new(ResultReturner { s: "1".to_string() }); + match rwlock.read().unwrap().to_number() { + Ok(n) => println!("Converted to number: {}", n), + Err(e) => println!("Could not convert {} to number", e), + }; +} + +fn should_trigger_lint_for_read_write_lock_for_loop() { + // For-in loops desugar to match expressions and are prone to the type of deadlock this lint is + // designed to look for. + let rwlock = RwLock::>::new(vec!["1".to_string()]); + for s in rwlock.read().unwrap().iter() { + println!("{}", s); + } +} + +fn do_bar(mutex: &Mutex) { + mutex.lock().unwrap().bar(); +} + +fn should_trigger_lint_without_significant_drop_in_arm() { + let mutex = Mutex::new(State {}); + + // Should trigger lint because the lifetime of the temporary MutexGuard is surprising because it + // is preserved until the end of the match, but there is no clear indication that this is the + // case. + match mutex.lock().unwrap().foo() { + true => do_bar(&mutex), + false => {}, + }; +} + +fn should_not_trigger_on_significant_iterator_drop() { + let lines = std::io::stdin().lines(); + for line in lines { + println!("foo: {}", line.unwrap()); + } +} + +fn main() {} diff --git a/tests/ui/significant_drop_in_scrutinee.rs b/tests/ui/significant_drop_in_scrutinee.rs index c65df9ece38c..17df9f88fff7 100644 --- a/tests/ui/significant_drop_in_scrutinee.rs +++ b/tests/ui/significant_drop_in_scrutinee.rs @@ -1,5 +1,5 @@ // FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934 -// // run-rustfix +// #![warn(clippy::significant_drop_in_scrutinee)] #![allow(dead_code, unused_assignments)] #![allow(clippy::match_single_binding, clippy::single_match, clippy::uninlined_format_args)] @@ -7,8 +7,7 @@ use std::num::ParseIntError; use std::ops::Deref; use std::sync::atomic::{AtomicU64, Ordering}; -use std::sync::RwLock; -use std::sync::{Mutex, MutexGuard}; +use std::sync::{Mutex, MutexGuard, RwLock}; struct State {} diff --git a/tests/ui/significant_drop_in_scrutinee.stderr b/tests/ui/significant_drop_in_scrutinee.stderr index 75063a8c987e..b56ace200a8b 100644 --- a/tests/ui/significant_drop_in_scrutinee.stderr +++ b/tests/ui/significant_drop_in_scrutinee.stderr @@ -1,5 +1,5 @@ error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:56:11 + --> $DIR/significant_drop_in_scrutinee.rs:55:11 | LL | match mutex.lock().unwrap().foo() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:142:11 + --> $DIR/significant_drop_in_scrutinee.rs:141:11 | LL | match s.lock_m().get_the_value() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:163:11 + --> $DIR/significant_drop_in_scrutinee.rs:162:11 | LL | match s.lock_m_m().get_the_value() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:211:11 + --> $DIR/significant_drop_in_scrutinee.rs:210:11 | LL | match counter.temp_increment().len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:234:16 + --> $DIR/significant_drop_in_scrutinee.rs:233:16 | LL | match (mutex1.lock().unwrap().s.len(), true) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL ~ match (value, true) { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:243:22 + --> $DIR/significant_drop_in_scrutinee.rs:242:22 | LL | match (true, mutex1.lock().unwrap().s.len(), true) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL ~ match (true, value, true) { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:253:16 + --> $DIR/significant_drop_in_scrutinee.rs:252:16 | LL | match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL ~ match (value, true, mutex2.lock().unwrap().s.len()) { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:253:54 + --> $DIR/significant_drop_in_scrutinee.rs:252:54 | LL | match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -153,7 +153,7 @@ LL ~ match (mutex1.lock().unwrap().s.len(), true, value) { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:264:15 + --> $DIR/significant_drop_in_scrutinee.rs:263:15 | LL | match mutex3.lock().unwrap().s.as_str() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL | }; = note: this might lead to deadlocks or other unexpected behavior error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:274:22 + --> $DIR/significant_drop_in_scrutinee.rs:273:22 | LL | match (true, mutex3.lock().unwrap().s.as_str()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +185,7 @@ LL | }; = note: this might lead to deadlocks or other unexpected behavior error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:293:11 + --> $DIR/significant_drop_in_scrutinee.rs:292:11 | LL | match mutex.lock().unwrap().s.len() > 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -204,7 +204,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:300:11 + --> $DIR/significant_drop_in_scrutinee.rs:299:11 | LL | match 1 < mutex.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -223,7 +223,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:318:11 + --> $DIR/significant_drop_in_scrutinee.rs:317:11 | LL | match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -244,7 +244,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:329:11 + --> $DIR/significant_drop_in_scrutinee.rs:328:11 | LL | match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -265,7 +265,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:364:11 + --> $DIR/significant_drop_in_scrutinee.rs:363:11 | LL | match get_mutex_guard().s.len() > 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -284,7 +284,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:381:11 + --> $DIR/significant_drop_in_scrutinee.rs:380:11 | LL | match match i { | ___________^ @@ -316,7 +316,7 @@ LL ~ match value | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:407:11 + --> $DIR/significant_drop_in_scrutinee.rs:406:11 | LL | match if i > 1 { | ___________^ @@ -349,7 +349,7 @@ LL ~ match value | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:461:11 + --> $DIR/significant_drop_in_scrutinee.rs:460:11 | LL | match s.lock().deref().deref() { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -367,7 +367,7 @@ LL ~ match value { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:489:11 + --> $DIR/significant_drop_in_scrutinee.rs:488:11 | LL | match s.lock().deref().deref() { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -380,7 +380,7 @@ LL | }; = note: this might lead to deadlocks or other unexpected behavior error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:508:11 + --> $DIR/significant_drop_in_scrutinee.rs:507:11 | LL | match mutex.lock().unwrap().i = i { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -399,7 +399,7 @@ LL ~ match () { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:514:11 + --> $DIR/significant_drop_in_scrutinee.rs:513:11 | LL | match i = mutex.lock().unwrap().i { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -418,7 +418,7 @@ LL ~ match () { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:520:11 + --> $DIR/significant_drop_in_scrutinee.rs:519:11 | LL | match mutex.lock().unwrap().i += 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -437,7 +437,7 @@ LL ~ match () { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:526:11 + --> $DIR/significant_drop_in_scrutinee.rs:525:11 | LL | match i += mutex.lock().unwrap().i { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -456,7 +456,7 @@ LL ~ match () { | error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:589:11 + --> $DIR/significant_drop_in_scrutinee.rs:588:11 | LL | match rwlock.read().unwrap().to_number() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -467,7 +467,7 @@ LL | }; = note: this might lead to deadlocks or other unexpected behavior error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression - --> $DIR/significant_drop_in_scrutinee.rs:599:14 + --> $DIR/significant_drop_in_scrutinee.rs:598:14 | LL | for s in rwlock.read().unwrap().iter() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -478,7 +478,7 @@ LL | } = note: this might lead to deadlocks or other unexpected behavior error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression - --> $DIR/significant_drop_in_scrutinee.rs:614:11 + --> $DIR/significant_drop_in_scrutinee.rs:613:11 | LL | match mutex.lock().unwrap().foo() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/significant_drop_tightening.fixed b/tests/ui/significant_drop_tightening.fixed index da998c610bd2..eb8524167c4a 100644 --- a/tests/ui/significant_drop_tightening.fixed +++ b/tests/ui/significant_drop_tightening.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::significant_drop_tightening)] @@ -16,6 +16,41 @@ pub fn complex_return_triggers_the_lint() -> i32 { foo() } +pub fn issue_10413() { + let mutex = Mutex::new(Some(1)); + let opt = Some(1); + if opt.is_some() { + let lock = mutex.lock().unwrap(); + let _ = *lock; + if opt.is_some() { + let _ = *lock; + } + } +} + +pub fn issue_11128() { + use std::mem::drop as unlock; + + struct Foo { + droppable: Option>, + mutex: Mutex>, + } + + impl Drop for Foo { + fn drop(&mut self) { + if let Some(droppable) = self.droppable.take() { + let lock = self.mutex.lock().unwrap(); + let idx_opt = lock.iter().copied().find(|el| Some(el) == droppable.first()); + if let Some(idx) = idx_opt { + let local_droppable = vec![lock.first().copied().unwrap_or_default()]; + unlock(lock); + drop(local_droppable); + } + } + } + } +} + pub fn path_return_can_be_ignored() -> i32 { let mutex = Mutex::new(1); let lock = mutex.lock().unwrap(); diff --git a/tests/ui/significant_drop_tightening.rs b/tests/ui/significant_drop_tightening.rs index 83823f95f68a..f7fa65ea9227 100644 --- a/tests/ui/significant_drop_tightening.rs +++ b/tests/ui/significant_drop_tightening.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::significant_drop_tightening)] @@ -15,6 +15,41 @@ pub fn complex_return_triggers_the_lint() -> i32 { foo() } +pub fn issue_10413() { + let mutex = Mutex::new(Some(1)); + let opt = Some(1); + if opt.is_some() { + let lock = mutex.lock().unwrap(); + let _ = *lock; + if opt.is_some() { + let _ = *lock; + } + } +} + +pub fn issue_11128() { + use std::mem::drop as unlock; + + struct Foo { + droppable: Option>, + mutex: Mutex>, + } + + impl Drop for Foo { + fn drop(&mut self) { + if let Some(droppable) = self.droppable.take() { + let lock = self.mutex.lock().unwrap(); + let idx_opt = lock.iter().copied().find(|el| Some(el) == droppable.first()); + if let Some(idx) = idx_opt { + let local_droppable = vec![lock.first().copied().unwrap_or_default()]; + unlock(lock); + drop(local_droppable); + } + } + } + } +} + pub fn path_return_can_be_ignored() -> i32 { let mutex = Mutex::new(1); let lock = mutex.lock().unwrap(); diff --git a/tests/ui/significant_drop_tightening.stderr b/tests/ui/significant_drop_tightening.stderr index ab8ce356ec7b..ca4fede17c93 100644 --- a/tests/ui/significant_drop_tightening.stderr +++ b/tests/ui/significant_drop_tightening.stderr @@ -23,7 +23,7 @@ LL + drop(lock); | error: temporary with significant `Drop` can be early dropped - --> $DIR/significant_drop_tightening.rs:44:13 + --> $DIR/significant_drop_tightening.rs:79:13 | LL | / { LL | | let mutex = Mutex::new(1i32); @@ -43,7 +43,7 @@ LL + drop(lock); | error: temporary with significant `Drop` can be early dropped - --> $DIR/significant_drop_tightening.rs:65:13 + --> $DIR/significant_drop_tightening.rs:100:13 | LL | / { LL | | let mutex = Mutex::new(1i32); @@ -67,7 +67,7 @@ LL + | error: temporary with significant `Drop` can be early dropped - --> $DIR/significant_drop_tightening.rs:71:17 + --> $DIR/significant_drop_tightening.rs:106:17 | LL | / { LL | | let mutex = Mutex::new(vec![1i32]); diff --git a/tests/ui/single_call_fn.rs b/tests/ui/single_call_fn.rs new file mode 100644 index 000000000000..781c0684a73d --- /dev/null +++ b/tests/ui/single_call_fn.rs @@ -0,0 +1,110 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +//@compile-flags: --test +>>>>>>> 2cd4a9182 (Ignore functions annotated with `#[test]`) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) +#![allow(clippy::redundant_closure_call, unused)] +======= +//@aux-build:proc_macros.rs +<<<<<<< HEAD +#![allow(unused)] +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) +======= +#![allow(clippy::redundant_closure_call, unused)] +>>>>>>> a8605269b (add test for closures) +#![warn(clippy::single_call_fn)] +#![no_main] + +#[macro_use] +extern crate proc_macros; + +// Do not lint since it's public +pub fn f() {} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a8605269b (add test for closures) +fn i() {} +fn j() {} + +fn h() { + // Linted + let a = i; + // Do not lint closures + let a = (|| { + // Not linted + a(); + // Imo, it's reasonable to lint this as the function is still only being used once. Just in + // a closure. + j(); + }); + a(); +} + +<<<<<<< HEAD +======= +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) +======= +>>>>>>> a8605269b (add test for closures) +fn g() { + f(); +} + +fn c() { + println!("really"); + println!("long"); + println!("function..."); +} + +fn d() { + c(); +} + +fn a() {} + +fn b() { + a(); + + external! { + fn lol() { + lol_inner(); + } + fn lol_inner() {} + } + with_span! { + span + fn lol2() { + lol2_inner(); + } + fn lol2_inner() {} + } +} + +fn e() { + b(); + b(); +} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2cd4a9182 (Ignore functions annotated with `#[test]`) + +#[test] +fn k() {} + +#[test] +fn l() { + k(); +} +<<<<<<< HEAD +======= +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) +======= +>>>>>>> 2cd4a9182 (Ignore functions annotated with `#[test]`) diff --git a/tests/ui/single_call_fn.stderr b/tests/ui/single_call_fn.stderr new file mode 100644 index 000000000000..de533b990222 --- /dev/null +++ b/tests/ui/single_call_fn.stderr @@ -0,0 +1,146 @@ +error: this function is only used once +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/single_call_fn.rs:33:1 +======= + --> $DIR/single_call_fn.rs:26:1 + | +LL | fn a() {} + | ^^^^^^^^^ + | +help: used here + --> $DIR/single_call_fn.rs:29:5 + | +LL | a(); + | ^ + = note: `-D clippy::single-call-fn` implied by `-D warnings` + +error: this function is only used once + --> $DIR/single_call_fn.rs:16:1 +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) +======= + --> $DIR/single_call_fn.rs:33:1 +>>>>>>> a8605269b (add test for closures) +======= + --> $DIR/single_call_fn.rs:34:1 +>>>>>>> 2cd4a9182 (Ignore functions annotated with `#[test]`) +======= + --> $DIR/single_call_fn.rs:33:1 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | / fn c() { +LL | | println!("really"); +LL | | println!("long"); +LL | | println!("function..."); +LL | | } + | |_^ + | +help: used here +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/single_call_fn.rs:40:5 +======= + --> $DIR/single_call_fn.rs:41:5 +>>>>>>> 2cd4a9182 (Ignore functions annotated with `#[test]`) +======= + --> $DIR/single_call_fn.rs:40:5 +>>>>>>> 5bd97ac17 (Update tests) + | +LL | c(); + | ^ + = note: `-D clippy::single-call-fn` implied by `-D warnings` + +error: this function is only used once + --> $DIR/single_call_fn.rs:12:1 + | +LL | fn i() {} + | ^^^^^^^^^ + | +help: used here + --> $DIR/single_call_fn.rs:17:13 + | +LL | let a = i; + | ^ + +error: this function is only used once + --> $DIR/single_call_fn.rs:43:1 + | +LL | fn a() {} + | ^^^^^^^^^ + | +help: used here + --> $DIR/single_call_fn.rs:46:5 + | +LL | a(); + | ^ + +error: this function is only used once + --> $DIR/single_call_fn.rs:13:1 + | +LL | fn j() {} + | ^^^^^^^^^ + | +help: used here + --> $DIR/single_call_fn.rs:24:9 + | +LL | j(); + | ^ + +error: aborting due to 4 previous errors +======= + --> $DIR/single_call_fn.rs:23:5 +======= + --> $DIR/single_call_fn.rs:40:5 +>>>>>>> a8605269b (add test for closures) + | +LL | c(); + | ^ + = note: `-D clippy::single-call-fn` implied by `-D warnings` + +<<<<<<< HEAD +error: aborting due to 2 previous errors +>>>>>>> 07dbcbda1 (new lint `single_call_fn`) +======= +error: this function is only used once + --> $DIR/single_call_fn.rs:12:1 + | +LL | fn i() {} + | ^^^^^^^^^ + | +help: used here + --> $DIR/single_call_fn.rs:17:13 + | +LL | let a = i; + | ^ + +error: this function is only used once + --> $DIR/single_call_fn.rs:43:1 + | +LL | fn a() {} + | ^^^^^^^^^ + | +help: used here + --> $DIR/single_call_fn.rs:46:5 + | +LL | a(); + | ^ + +error: this function is only used once + --> $DIR/single_call_fn.rs:13:1 + | +LL | fn j() {} + | ^^^^^^^^^ + | +help: used here + --> $DIR/single_call_fn.rs:24:9 + | +LL | j(); + | ^ + +error: aborting due to 4 previous errors +>>>>>>> a8605269b (add test for closures) + diff --git a/tests/ui/single_char_add_str.fixed b/tests/ui/single_char_add_str.fixed index 63a6d37a9cce..67c9ce0a0bca 100644 --- a/tests/ui/single_char_add_str.fixed +++ b/tests/ui/single_char_add_str.fixed @@ -1,5 +1,18 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::single_char_add_str)] +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes)] +======= +#![allow(clippy::needless_raw_string_hashes)] +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= +#![allow(clippy::needless_raw_string, clippy::needless_raw_string_hashes)] +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= +#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes)] +>>>>>>> 8cb6c8699 (change category and refactor) macro_rules! get_string { () => { diff --git a/tests/ui/single_char_add_str.rs b/tests/ui/single_char_add_str.rs index a799ea7d8856..5419cab411ff 100644 --- a/tests/ui/single_char_add_str.rs +++ b/tests/ui/single_char_add_str.rs @@ -1,5 +1,18 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::single_char_add_str)] +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes)] +======= +#![allow(clippy::needless_raw_string_hashes)] +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= +#![allow(clippy::needless_raw_string, clippy::needless_raw_string_hashes)] +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= +#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes)] +>>>>>>> 8cb6c8699 (change category and refactor) macro_rules! get_string { () => { diff --git a/tests/ui/single_char_add_str.stderr b/tests/ui/single_char_add_str.stderr index 55d91583ad04..3f93c18470ea 100644 --- a/tests/ui/single_char_add_str.stderr +++ b/tests/ui/single_char_add_str.stderr @@ -1,5 +1,5 @@ error: calling `push_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:14:5 + --> $DIR/single_char_add_str.rs:15:5 | LL | string.push_str("R"); | ^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('R')` @@ -7,85 +7,85 @@ LL | string.push_str("R"); = note: `-D clippy::single-char-add-str` implied by `-D warnings` error: calling `push_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:15:5 + --> $DIR/single_char_add_str.rs:16:5 | LL | string.push_str("'"); | ^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('/'')` error: calling `push_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:20:5 + --> $DIR/single_char_add_str.rs:21:5 | LL | string.push_str("/x52"); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('/x52')` error: calling `push_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:21:5 + --> $DIR/single_char_add_str.rs:22:5 | LL | string.push_str("/u{0052}"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('/u{0052}')` error: calling `push_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:22:5 + --> $DIR/single_char_add_str.rs:23:5 | LL | string.push_str(r##"a"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('a')` error: calling `push_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:24:5 + --> $DIR/single_char_add_str.rs:25:5 | LL | get_string!().push_str("ö"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `get_string!().push('ö')` error: calling `insert_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:29:5 + --> $DIR/single_char_add_str.rs:30:5 | LL | string.insert_str(0, "R"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, 'R')` error: calling `insert_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:30:5 + --> $DIR/single_char_add_str.rs:31:5 | LL | string.insert_str(1, "'"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(1, '/'')` error: calling `insert_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:35:5 + --> $DIR/single_char_add_str.rs:36:5 | LL | string.insert_str(0, "/x52"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '/x52')` error: calling `insert_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:36:5 + --> $DIR/single_char_add_str.rs:37:5 | LL | string.insert_str(0, "/u{0052}"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '/u{0052}')` error: calling `insert_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:38:5 + --> $DIR/single_char_add_str.rs:39:5 | LL | string.insert_str(x, r##"a"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(x, 'a')` error: calling `insert_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:40:5 + --> $DIR/single_char_add_str.rs:41:5 | LL | string.insert_str(Y, r##"a"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, 'a')` error: calling `insert_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:41:5 + --> $DIR/single_char_add_str.rs:42:5 | LL | string.insert_str(Y, r##"""##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '"')` error: calling `insert_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:42:5 + --> $DIR/single_char_add_str.rs:43:5 | LL | string.insert_str(Y, r##"'"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '/'')` error: calling `insert_str()` using a single-character string literal - --> $DIR/single_char_add_str.rs:44:5 + --> $DIR/single_char_add_str.rs:45:5 | LL | get_string!().insert_str(1, "?"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `get_string!().insert(1, '?')` diff --git a/tests/ui/single_char_pattern.fixed b/tests/ui/single_char_pattern.fixed index 68e26726724b..d6313cd57103 100644 --- a/tests/ui/single_char_pattern.fixed +++ b/tests/ui/single_char_pattern.fixed @@ -1,6 +1,18 @@ -// run-rustfix +//@run-rustfix -#![allow(unused_must_use)] +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes, unused_must_use)] +======= +#![allow(clippy::needless_raw_string_hashes, unused_must_use)] +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= +#![allow(clippy::needless_raw_string, clippy::needless_raw_string_hashes, unused_must_use)] +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= +#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes, unused_must_use)] +>>>>>>> 8cb6c8699 (change category and refactor) use std::collections::HashSet; diff --git a/tests/ui/single_char_pattern.rs b/tests/ui/single_char_pattern.rs index 186202d78ec5..94d4e76dfa7a 100644 --- a/tests/ui/single_char_pattern.rs +++ b/tests/ui/single_char_pattern.rs @@ -1,6 +1,18 @@ -// run-rustfix +//@run-rustfix -#![allow(unused_must_use)] +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes, unused_must_use)] +======= +#![allow(clippy::needless_raw_string_hashes, unused_must_use)] +>>>>>>> 1bf74fc30 (add `needless_raw_string_hashes` lint) +======= +#![allow(clippy::needless_raw_string, clippy::needless_raw_string_hashes, unused_must_use)] +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= +#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes, unused_must_use)] +>>>>>>> 8cb6c8699 (change category and refactor) use std::collections::HashSet; diff --git a/tests/ui/single_char_pattern.stderr b/tests/ui/single_char_pattern.stderr index 5564aac674d9..5ae2450c2268 100644 --- a/tests/ui/single_char_pattern.stderr +++ b/tests/ui/single_char_pattern.stderr @@ -226,13 +226,13 @@ error: single-character string constant used as pattern --> $DIR/single_char_pattern.rs:65:13 | LL | x.split(r#"/"#); - | ^^^^^^ help: try using a `char` instead: `'/'` + | ^^^^^^ help: try using a `char` instead: `'//'` error: single-character string constant used as pattern --> $DIR/single_char_pattern.rs:66:13 | LL | x.split(r"/"); - | ^^^^ help: try using a `char` instead: `'/'` + | ^^^^ help: try using a `char` instead: `'//'` error: aborting due to 39 previous errors diff --git a/tests/ui/single_component_path_imports.fixed b/tests/ui/single_component_path_imports.fixed index 8c96c4715d30..b6b6b0288c52 100644 --- a/tests/ui/single_component_path_imports.fixed +++ b/tests/ui/single_component_path_imports.fixed @@ -1,11 +1,15 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::single_component_path_imports)] #![allow(unused_imports)] use core; + + use serde as edres; + pub use serde; + use std; macro_rules! m { diff --git a/tests/ui/single_component_path_imports.rs b/tests/ui/single_component_path_imports.rs index 8434bf7eaf1f..a8c4d8990856 100644 --- a/tests/ui/single_component_path_imports.rs +++ b/tests/ui/single_component_path_imports.rs @@ -1,11 +1,15 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::single_component_path_imports)] #![allow(unused_imports)] use core; + use regex; + use serde as edres; + pub use serde; + use std; macro_rules! m { diff --git a/tests/ui/single_component_path_imports.stderr b/tests/ui/single_component_path_imports.stderr index d69a86470a5e..853a2fe0e7bf 100644 --- a/tests/ui/single_component_path_imports.stderr +++ b/tests/ui/single_component_path_imports.stderr @@ -1,5 +1,5 @@ error: this import is redundant - --> $DIR/single_component_path_imports.rs:6:1 + --> $DIR/single_component_path_imports.rs:7:1 | LL | use regex; | ^^^^^^^^^^ help: remove it entirely @@ -7,7 +7,7 @@ LL | use regex; = note: `-D clippy::single-component-path-imports` implied by `-D warnings` error: this import is redundant - --> $DIR/single_component_path_imports.rs:29:5 + --> $DIR/single_component_path_imports.rs:33:5 | LL | use regex; | ^^^^^^^^^^ help: remove it entirely diff --git a/tests/ui/single_component_path_imports_nested_first.rs b/tests/ui/single_component_path_imports_nested_first.rs index c75beb747861..d6243c19f554 100644 --- a/tests/ui/single_component_path_imports_nested_first.rs +++ b/tests/ui/single_component_path_imports_nested_first.rs @@ -2,7 +2,9 @@ #![allow(unused_imports)] use regex; + use serde as edres; + pub use serde; fn main() { diff --git a/tests/ui/single_component_path_imports_nested_first.stderr b/tests/ui/single_component_path_imports_nested_first.stderr index 330f285202d0..ff148355e121 100644 --- a/tests/ui/single_component_path_imports_nested_first.stderr +++ b/tests/ui/single_component_path_imports_nested_first.stderr @@ -7,7 +7,7 @@ LL | use regex; = note: `-D clippy::single-component-path-imports` implied by `-D warnings` error: this import is redundant - --> $DIR/single_component_path_imports_nested_first.rs:13:10 + --> $DIR/single_component_path_imports_nested_first.rs:15:10 | LL | use {regex, serde}; | ^^^^^ @@ -15,7 +15,7 @@ LL | use {regex, serde}; = help: remove this import error: this import is redundant - --> $DIR/single_component_path_imports_nested_first.rs:13:17 + --> $DIR/single_component_path_imports_nested_first.rs:15:17 | LL | use {regex, serde}; | ^^^^^ diff --git a/tests/ui/single_component_path_imports_self_after.rs b/tests/ui/single_component_path_imports_self_after.rs index 48e8e530261b..5723d480a2e1 100644 --- a/tests/ui/single_component_path_imports_self_after.rs +++ b/tests/ui/single_component_path_imports_self_after.rs @@ -2,6 +2,7 @@ #![allow(unused_imports)] use self::regex::{Regex as xeger, RegexSet as tesxeger}; +#[rustfmt::skip] pub use self::{ regex::{Regex, RegexSet}, some_mod::SomeType, diff --git a/tests/ui/single_component_path_imports_self_before.rs b/tests/ui/single_component_path_imports_self_before.rs index 4fb0cf40b6e0..8a4fbf0dc5b6 100644 --- a/tests/ui/single_component_path_imports_self_before.rs +++ b/tests/ui/single_component_path_imports_self_before.rs @@ -4,6 +4,7 @@ use regex; use self::regex::{Regex as xeger, RegexSet as tesxeger}; +#[rustfmt::skip] pub use self::{ regex::{Regex, RegexSet}, some_mod::SomeType, diff --git a/tests/ui/single_element_loop.fixed b/tests/ui/single_element_loop.fixed index a0dcc0172e8b..598f259415da 100644 --- a/tests/ui/single_element_loop.fixed +++ b/tests/ui/single_element_loop.fixed @@ -1,6 +1,8 @@ -// run-rustfix +//@run-rustfix // Tests from for_loop.rs that don't have suggestions +#![allow(clippy::single_range_in_vec_init)] + #[warn(clippy::single_element_loop)] fn main() { let item1 = 2; diff --git a/tests/ui/single_element_loop.rs b/tests/ui/single_element_loop.rs index bc014035c98a..3fc461735a49 100644 --- a/tests/ui/single_element_loop.rs +++ b/tests/ui/single_element_loop.rs @@ -1,6 +1,8 @@ -// run-rustfix +//@run-rustfix // Tests from for_loop.rs that don't have suggestions +#![allow(clippy::single_range_in_vec_init)] + #[warn(clippy::single_element_loop)] fn main() { let item1 = 2; diff --git a/tests/ui/single_element_loop.stderr b/tests/ui/single_element_loop.stderr index 14437a59745e..c40c6198945a 100644 --- a/tests/ui/single_element_loop.stderr +++ b/tests/ui/single_element_loop.stderr @@ -1,5 +1,5 @@ error: for loop over a single element - --> $DIR/single_element_loop.rs:7:5 + --> $DIR/single_element_loop.rs:9:5 | LL | / for item in &[item1] { LL | | dbg!(item); @@ -16,7 +16,7 @@ LL + } | error: for loop over a single element - --> $DIR/single_element_loop.rs:11:5 + --> $DIR/single_element_loop.rs:13:5 | LL | / for item in [item1].iter() { LL | | dbg!(item); @@ -32,7 +32,7 @@ LL + } | error: for loop over a single element - --> $DIR/single_element_loop.rs:15:5 + --> $DIR/single_element_loop.rs:17:5 | LL | / for item in &[0..5] { LL | | dbg!(item); @@ -48,7 +48,7 @@ LL + } | error: for loop over a single element - --> $DIR/single_element_loop.rs:19:5 + --> $DIR/single_element_loop.rs:21:5 | LL | / for item in [0..5].iter_mut() { LL | | dbg!(item); @@ -64,7 +64,7 @@ LL + } | error: for loop over a single element - --> $DIR/single_element_loop.rs:23:5 + --> $DIR/single_element_loop.rs:25:5 | LL | / for item in [0..5] { LL | | dbg!(item); @@ -80,7 +80,7 @@ LL + } | error: for loop over a single element - --> $DIR/single_element_loop.rs:27:5 + --> $DIR/single_element_loop.rs:29:5 | LL | / for item in [0..5].into_iter() { LL | | dbg!(item); @@ -96,7 +96,7 @@ LL + } | error: for loop over a single element - --> $DIR/single_element_loop.rs:46:5 + --> $DIR/single_element_loop.rs:48:5 | LL | / for _ in [42] { LL | | let _f = |n: u32| { diff --git a/tests/ui/single_match.fixed b/tests/ui/single_match.fixed new file mode 100644 index 000000000000..30412026e54d --- /dev/null +++ b/tests/ui/single_match.fixed @@ -0,0 +1,277 @@ +//@run-rustfix +#![warn(clippy::single_match)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 26f50395b (Add `needless_if` lint) +#![allow( + unused, + clippy::uninlined_format_args, + clippy::needless_if, + clippy::redundant_pattern_matching +)] +<<<<<<< HEAD +======= +#![allow(unused, clippy::uninlined_format_args, clippy::redundant_pattern_matching)] +>>>>>>> ed935de08 (Run-rustfix) +======= +>>>>>>> 26f50395b (Add `needless_if` lint) +fn dummy() {} + +fn single_match() { + let x = Some(1u8); + + if let Some(y) = x { + println!("{:?}", y); + }; + + let x = Some(1u8); + if let Some(y) = x { println!("{:?}", y) } + + let z = (1u8, 1u8); + if let (2..=3, 7..=9) = z { dummy() }; + + // Not linted (pattern guards used) + match x { + Some(y) if y == 0 => println!("{:?}", y), + _ => (), + } + + // Not linted (no block with statements in the single arm) + match z { + (2..=3, 7..=9) => println!("{:?}", z), + _ => println!("nope"), + } +} + +enum Foo { + Bar, + Baz(u8), +} +use std::borrow::Cow; +use Foo::*; + +fn single_match_know_enum() { + let x = Some(1u8); + let y: Result<_, i8> = Ok(1i8); + + if let Some(y) = x { dummy() }; + + if let Ok(y) = y { dummy() }; + + let c = Cow::Borrowed(""); + + if let Cow::Borrowed(..) = c { dummy() }; + + let z = Foo::Bar; + // no warning + match z { + Bar => println!("42"), + Baz(_) => (), + } + + match z { + Baz(_) => println!("42"), + Bar => (), + } +} + +// issue #173 +fn if_suggestion() { + let x = "test"; + if x == "test" { println!() } + + #[derive(PartialEq, Eq)] + enum Foo { + A, + B, + C(u32), + } + + let x = Foo::A; + if x == Foo::A { println!() } + + const FOO_C: Foo = Foo::C(0); + if x == FOO_C { println!() } + + if x == Foo::A { println!() } + + let x = &x; + if x == &Foo::A { println!() } + + enum Bar { + A, + B, + } + impl PartialEq for Bar { + fn eq(&self, rhs: &Self) -> bool { + matches!((self, rhs), (Self::A, Self::A) | (Self::B, Self::B)) + } + } + impl Eq for Bar {} + + let x = Bar::A; + if let Bar::A = x { println!() } + + // issue #7038 + struct X; + let x = Some(X); + if let None = x { println!() }; +} + +// See: issue #8282 +fn ranges() { + enum E { + V, + } + let x = (Some(E::V), Some(42)); + + // Don't lint, because the `E` enum can be extended with additional fields later. Thus, the + // proposed replacement to `if let Some(E::V)` may hide non-exhaustive warnings that appeared + // because of `match` construction. + match x { + (Some(E::V), _) => {}, + (None, _) => {}, + } + + // lint + if let (Some(_), _) = x {} + + // lint + if let (Some(E::V), _) = x { todo!() } + + // lint + if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {} + + // Don't lint, see above. + match (Some(E::V), Some(E::V), Some(E::V)) { + (.., Some(E::V), _) => {}, + (.., None, _) => {}, + } + + // Don't lint, see above. + match (Some(E::V), Some(E::V), Some(E::V)) { + (Some(E::V), ..) => {}, + (None, ..) => {}, + } + + // Don't lint, see above. + match (Some(E::V), Some(E::V), Some(E::V)) { + (_, Some(E::V), ..) => {}, + (_, None, ..) => {}, + } +} + +fn skip_type_aliases() { + enum OptionEx { + Some(i32), + None, + } + enum ResultEx { + Err(i32), + Ok(i32), + } + + use OptionEx::{None, Some}; + use ResultEx::{Err, Ok}; + + // don't lint + match Err(42) { + Ok(_) => dummy(), + Err(_) => (), + }; + + // don't lint + match Some(1i32) { + Some(_) => dummy(), + None => (), + }; +} + +macro_rules! single_match { + ($num:literal) => { + match $num { + 15 => println!("15"), + _ => (), + } + }; +} + +fn main() { + single_match!(5); + + // Don't lint + let _ = match Some(0) { + #[cfg(feature = "foo")] + Some(10) => 11, + Some(x) => x, + _ => 0, + }; +} + +fn issue_10808(bar: Option) { + if let Some(v) = bar { unsafe { + let r = &v as *const i32; + println!("{}", *r); + } } + + if let Some(v) = bar { + unsafe { + let r = &v as *const i32; + println!("{}", *r); + } + } +} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> d7e723441 ([`single_match`]: don't lint if block contains comments) + +mod issue8634 { + struct SomeError(i32, i32); + + fn foo(x: Result) { + match x { + Ok(y) => { + println!("Yay! {y}"); + }, + Err(()) => { + // Ignore this error because blah blah blah. + }, + } + } + + fn bar(x: Result) { + match x { + Ok(y) => { + println!("Yay! {y}"); + }, + Err(_) => { + // TODO: Process the error properly. + }, + } + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2e856fa99 (add test for block comment and add note to description) + + fn block_comment(x: Result) { + match x { + Ok(y) => { + println!("Yay! {y}"); + }, + Err(_) => { + /* + let's make sure that this also + does not lint block comments. + */ + }, + } + } +} +======= +>>>>>>> ed935de08 (Run-rustfix) +======= +} +>>>>>>> d7e723441 ([`single_match`]: don't lint if block contains comments) diff --git a/tests/ui/single_match.rs b/tests/ui/single_match.rs index d0c9b7b5663e..9128a789f918 100644 --- a/tests/ui/single_match.rs +++ b/tests/ui/single_match.rs @@ -1,6 +1,26 @@ +//@run-rustfix #![warn(clippy::single_match)] -#![allow(clippy::uninlined_format_args)] - +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 26f50395b (Add `needless_if` lint) +#![allow( + unused, + clippy::uninlined_format_args, + clippy::needless_if, + clippy::redundant_pattern_matching +)] +<<<<<<< HEAD +======= +#![allow(unused, clippy::uninlined_format_args)] + +>>>>>>> 1c277d1be (Unit tests highlighting unsafe match issue) +======= +#![allow(unused, clippy::uninlined_format_args, clippy::redundant_pattern_matching)] +>>>>>>> ed935de08 (Run-rustfix) +======= +>>>>>>> 26f50395b (Add `needless_if` lint) fn dummy() {} fn single_match() { @@ -244,3 +264,87 @@ fn main() { _ => 0, }; } + +fn issue_10808(bar: Option) { + match bar { + Some(v) => unsafe { + let r = &v as *const i32; + println!("{}", *r); + }, + _ => {}, + } + + match bar { +<<<<<<< HEAD +<<<<<<< HEAD + #[rustfmt::skip] + Some(v) => { +======= + Some(v) => { + // this comment prevents rustfmt from collapsing the block +>>>>>>> 1c277d1be (Unit tests highlighting unsafe match issue) +======= + #[rustfmt::skip] + Some(v) => { +>>>>>>> 9fd34e0c7 (Use #[rustfmt::skip]) + unsafe { + let r = &v as *const i32; + println!("{}", *r); + } + }, + _ => {}, + } +} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> d7e723441 ([`single_match`]: don't lint if block contains comments) + +mod issue8634 { + struct SomeError(i32, i32); + + fn foo(x: Result) { + match x { + Ok(y) => { + println!("Yay! {y}"); + }, + Err(()) => { + // Ignore this error because blah blah blah. + }, + } + } + + fn bar(x: Result) { + match x { + Ok(y) => { + println!("Yay! {y}"); + }, + Err(_) => { + // TODO: Process the error properly. + }, + } + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 2e856fa99 (add test for block comment and add note to description) + + fn block_comment(x: Result) { + match x { + Ok(y) => { + println!("Yay! {y}"); + }, + Err(_) => { + /* + let's make sure that this also + does not lint block comments. + */ + }, + } + } +} +======= +>>>>>>> 1c277d1be (Unit tests highlighting unsafe match issue) +======= +} +>>>>>>> d7e723441 ([`single_match`]: don't lint if block contains comments) diff --git a/tests/ui/single_match.stderr b/tests/ui/single_match.stderr index 7cecc1b73950..069cf932f5f9 100644 --- a/tests/ui/single_match.stderr +++ b/tests/ui/single_match.stderr @@ -1,5 +1,5 @@ error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match.rs:9:5 + --> $DIR/single_match.rs:14:5 | LL | / match x { LL | | Some(y) => { @@ -10,7 +10,7 @@ LL | | }; | |_____^ | = note: `-D clippy::single-match` implied by `-D warnings` -help: try this +help: try | LL ~ if let Some(y) = x { LL + println!("{:?}", y); @@ -18,7 +18,7 @@ LL ~ }; | error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match.rs:17:5 + --> $DIR/single_match.rs:22:5 | LL | / match x { LL | | // Note the missing block braces. @@ -27,133 +27,206 @@ LL | | // is expanded before we can do anything. LL | | Some(y) => println!("{:?}", y), LL | | _ => (), LL | | } - | |_____^ help: try this: `if let Some(y) = x { println!("{:?}", y) }` + | |_____^ help: try: `if let Some(y) = x { println!("{:?}", y) }` error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match.rs:26:5 + --> $DIR/single_match.rs:31:5 | LL | / match z { LL | | (2..=3, 7..=9) => dummy(), LL | | _ => {}, LL | | }; - | |_____^ help: try this: `if let (2..=3, 7..=9) = z { dummy() }` + | |_____^ help: try: `if let (2..=3, 7..=9) = z { dummy() }` error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match.rs:55:5 + --> $DIR/single_match.rs:60:5 | LL | / match x { LL | | Some(y) => dummy(), LL | | None => (), LL | | }; - | |_____^ help: try this: `if let Some(y) = x { dummy() }` + | |_____^ help: try: `if let Some(y) = x { dummy() }` error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match.rs:60:5 + --> $DIR/single_match.rs:65:5 | LL | / match y { LL | | Ok(y) => dummy(), LL | | Err(..) => (), LL | | }; - | |_____^ help: try this: `if let Ok(y) = y { dummy() }` + | |_____^ help: try: `if let Ok(y) = y { dummy() }` error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match.rs:67:5 + --> $DIR/single_match.rs:72:5 | LL | / match c { LL | | Cow::Borrowed(..) => dummy(), LL | | Cow::Owned(..) => (), LL | | }; - | |_____^ help: try this: `if let Cow::Borrowed(..) = c { dummy() }` + | |_____^ help: try: `if let Cow::Borrowed(..) = c { dummy() }` error: you seem to be trying to use `match` for an equality check. Consider using `if` - --> $DIR/single_match.rs:88:5 + --> $DIR/single_match.rs:93:5 | LL | / match x { LL | | "test" => println!(), LL | | _ => (), LL | | } - | |_____^ help: try this: `if x == "test" { println!() }` + | |_____^ help: try: `if x == "test" { println!() }` error: you seem to be trying to use `match` for an equality check. Consider using `if` - --> $DIR/single_match.rs:101:5 + --> $DIR/single_match.rs:106:5 | LL | / match x { LL | | Foo::A => println!(), LL | | _ => (), LL | | } - | |_____^ help: try this: `if x == Foo::A { println!() }` + | |_____^ help: try: `if x == Foo::A { println!() }` error: you seem to be trying to use `match` for an equality check. Consider using `if` - --> $DIR/single_match.rs:107:5 + --> $DIR/single_match.rs:112:5 | LL | / match x { LL | | FOO_C => println!(), LL | | _ => (), LL | | } - | |_____^ help: try this: `if x == FOO_C { println!() }` + | |_____^ help: try: `if x == FOO_C { println!() }` error: you seem to be trying to use `match` for an equality check. Consider using `if` - --> $DIR/single_match.rs:112:5 + --> $DIR/single_match.rs:117:5 | LL | / match &&x { LL | | Foo::A => println!(), LL | | _ => (), LL | | } - | |_____^ help: try this: `if x == Foo::A { println!() }` + | |_____^ help: try: `if x == Foo::A { println!() }` error: you seem to be trying to use `match` for an equality check. Consider using `if` - --> $DIR/single_match.rs:118:5 + --> $DIR/single_match.rs:123:5 | LL | / match &x { LL | | Foo::A => println!(), LL | | _ => (), LL | | } - | |_____^ help: try this: `if x == &Foo::A { println!() }` + | |_____^ help: try: `if x == &Foo::A { println!() }` error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match.rs:135:5 + --> $DIR/single_match.rs:140:5 | LL | / match x { LL | | Bar::A => println!(), LL | | _ => (), LL | | } - | |_____^ help: try this: `if let Bar::A = x { println!() }` + | |_____^ help: try: `if let Bar::A = x { println!() }` error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match.rs:143:5 + --> $DIR/single_match.rs:148:5 | LL | / match x { LL | | None => println!(), LL | | _ => (), LL | | }; - | |_____^ help: try this: `if let None = x { println!() }` + | |_____^ help: try: `if let None = x { println!() }` error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match.rs:165:5 + --> $DIR/single_match.rs:170:5 | LL | / match x { LL | | (Some(_), _) => {}, LL | | (None, _) => {}, LL | | } - | |_____^ help: try this: `if let (Some(_), _) = x {}` + | |_____^ help: try: `if let (Some(_), _) = x {}` error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match.rs:171:5 + --> $DIR/single_match.rs:176:5 | LL | / match x { LL | | (Some(E::V), _) => todo!(), LL | | (_, _) => {}, LL | | } - | |_____^ help: try this: `if let (Some(E::V), _) = x { todo!() }` + | |_____^ help: try: `if let (Some(E::V), _) = x { todo!() }` error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match.rs:177:5 + --> $DIR/single_match.rs:182:5 | LL | / match (Some(42), Some(E::V), Some(42)) { LL | | (.., Some(E::V), _) => {}, LL | | (..) => {}, LL | | } - | |_____^ help: try this: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}` + | |_____^ help: try: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}` + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/single_match.rs:254:5 +======= + --> $DIR/single_match.rs:249:5 +>>>>>>> e92614818 (Fix unsafe blocks) +======= + --> $DIR/single_match.rs:254:5 +>>>>>>> 26f50395b (Add `needless_if` lint) + | +LL | / match bar { +LL | | Some(v) => unsafe { +LL | | let r = &v as *const i32; +LL | | println!("{}", *r); +LL | | }, +LL | | _ => {}, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { unsafe { +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/single_match.rs:262:5 + | +LL | / match bar { +LL | | #[rustfmt::skip] +LL | | Some(v) => { +======= + --> $DIR/single_match.rs:257:5 +======= + --> $DIR/single_match.rs:262:5 +>>>>>>> 26f50395b (Add `needless_if` lint) + | +LL | / match bar { +LL | | #[rustfmt::skip] +LL | | Some(v) => { +<<<<<<< HEAD +LL | | // this comment prevents rustfmt from collapsing the block +>>>>>>> e92614818 (Fix unsafe blocks) +======= +>>>>>>> 9fd34e0c7 (Use #[rustfmt::skip]) +LL | | unsafe { +... | +LL | | _ => {}, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { +<<<<<<< HEAD +<<<<<<< HEAD +======= +LL + // this comment prevents rustfmt from collapsing the block +>>>>>>> e92614818 (Fix unsafe blocks) +======= +>>>>>>> 9fd34e0c7 (Use #[rustfmt::skip]) +LL + unsafe { +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } +LL + } + | -error: aborting due to 16 previous errors +error: aborting due to 18 previous errors diff --git a/tests/ui/single_match_else.fixed b/tests/ui/single_match_else.fixed new file mode 100644 index 000000000000..1d7b50318f1c --- /dev/null +++ b/tests/ui/single_match_else.fixed @@ -0,0 +1,181 @@ +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> ed935de08 (Run-rustfix) +======= +//@aux-build: proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) +#![warn(clippy::single_match_else)] +#![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)] +extern crate proc_macros; +use proc_macros::with_span; + +enum ExprNode { + ExprAddrOf, + Butterflies, + Unicorns, +} + +static NODE: ExprNode = ExprNode::Unicorns; + +fn unwrap_addr() -> Option<&'static ExprNode> { + let _ = if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else { + let x = 5; + None + }; + + // Don't lint + with_span!(span match ExprNode::Butterflies { + ExprNode::ExprAddrOf => Some(&NODE), + _ => { + let x = 5; + None + }, + }) +} + +macro_rules! unwrap_addr { + ($expression:expr) => { + match $expression { + ExprNode::ExprAddrOf => Some(&NODE), + _ => { + let x = 5; + None + }, + } + }; +} + +#[rustfmt::skip] +fn main() { + unwrap_addr!(ExprNode::Unicorns); + + // + // don't lint single exprs/statements + // + + // don't lint here + match Some(1) { + Some(a) => println!("${:?}", a), + None => return, + } + + // don't lint here + match Some(1) { + Some(a) => println!("${:?}", a), + None => { + return + }, + } + + // don't lint here + match Some(1) { + Some(a) => println!("${:?}", a), + None => { + return; + }, + } + + // + // lint multiple exprs/statements "else" blocks + // + + // lint here + if let Some(a) = Some(1) { println!("${:?}", a) } else { + println!("else block"); + return + } + + // lint here + if let Some(a) = Some(1) { println!("${:?}", a) } else { + println!("else block"); + return; + } + + // lint here + use std::convert::Infallible; + if let Ok(a) = Result::::Ok(1) { println!("${:?}", a) } else { + println!("else block"); + return; + } + + use std::borrow::Cow; + if let Cow::Owned(a) = Cow::from("moo") { println!("${:?}", a) } else { + println!("else block"); + return; + } +} + +fn issue_10808(bar: Option) { + if let Some(v) = bar { unsafe { + let r = &v as *const i32; + println!("{}", *r); + } } else { + println!("None1"); + println!("None2"); + } + + if let Some(v) = bar { + println!("Some"); + println!("{v}"); + } else { unsafe { + let v = 0; + let r = &v as *const i32; + println!("{}", *r); + } } + + if let Some(v) = bar { unsafe { + let r = &v as *const i32; + println!("{}", *r); + } } else { unsafe { + let v = 0; + let r = &v as *const i32; + println!("{}", *r); + } } + + if let Some(v) = bar { + unsafe { + let r = &v as *const i32; + println!("{}", *r); + } + } else { + println!("None"); + println!("None"); + } + + match bar { + Some(v) => { + println!("Some"); + println!("{v}"); + }, + #[rustfmt::skip] + None => { + unsafe { + let v = 0; + let r = &v as *const i32; + println!("{}", *r); + } + }, + } + + match bar { + #[rustfmt::skip] + Some(v) => { + unsafe { + let r = &v as *const i32; + println!("{}", *r); + } + }, + #[rustfmt::skip] + None => { + unsafe { + let v = 0; + let r = &v as *const i32; + println!("{}", *r); + } + }, + } +} diff --git a/tests/ui/single_match_else.rs b/tests/ui/single_match_else.rs index 3c86f41f3a6e..4e4d029abc5b 100644 --- a/tests/ui/single_match_else.rs +++ b/tests/ui/single_match_else.rs @@ -1,7 +1,25 @@ -// aux-build: proc_macros.rs +<<<<<<< HEAD +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::single_match_else)] -#![allow(clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)] +#![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)] +<<<<<<< HEAD +======= +>>>>>>> 1c277d1be (Unit tests highlighting unsafe match issue) +======= +//@aux-build: proc_macros.rs +======= +//@aux-build: proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) +#![warn(clippy::single_match_else)] +#![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)] +>>>>>>> ed935de08 (Run-rustfix) extern crate proc_macros; use proc_macros::with_span; @@ -115,3 +133,127 @@ fn main() { } } } + +fn issue_10808(bar: Option) { + match bar { + Some(v) => unsafe { + let r = &v as *const i32; + println!("{}", *r); + }, + None => { + println!("None1"); + println!("None2"); + }, + } + + match bar { + Some(v) => { + println!("Some"); + println!("{v}"); + }, + None => unsafe { + let v = 0; + let r = &v as *const i32; + println!("{}", *r); + }, + } + + match bar { + Some(v) => unsafe { + let r = &v as *const i32; + println!("{}", *r); + }, + None => unsafe { + let v = 0; + let r = &v as *const i32; + println!("{}", *r); + }, + } + + match bar { +<<<<<<< HEAD +<<<<<<< HEAD + #[rustfmt::skip] + Some(v) => { +======= + Some(v) => { + // this comment prevents rustfmt from collapsing the block +>>>>>>> 1c277d1be (Unit tests highlighting unsafe match issue) +======= + #[rustfmt::skip] + Some(v) => { +>>>>>>> 9fd34e0c7 (Use #[rustfmt::skip]) + unsafe { + let r = &v as *const i32; + println!("{}", *r); + } + }, + None => { + println!("None"); + println!("None"); + }, + } + + match bar { + Some(v) => { + println!("Some"); + println!("{v}"); + }, +<<<<<<< HEAD +<<<<<<< HEAD + #[rustfmt::skip] + None => { +======= + None => { + // this comment prevents rustfmt from collapsing the block +>>>>>>> 1c277d1be (Unit tests highlighting unsafe match issue) +======= + #[rustfmt::skip] + None => { +>>>>>>> 9fd34e0c7 (Use #[rustfmt::skip]) + unsafe { + let v = 0; + let r = &v as *const i32; + println!("{}", *r); + } + }, + } + + match bar { +<<<<<<< HEAD +<<<<<<< HEAD + #[rustfmt::skip] + Some(v) => { +======= + Some(v) => { + // this comment prevents rustfmt from collapsing the block +>>>>>>> 1c277d1be (Unit tests highlighting unsafe match issue) +======= + #[rustfmt::skip] + Some(v) => { +>>>>>>> 9fd34e0c7 (Use #[rustfmt::skip]) + unsafe { + let r = &v as *const i32; + println!("{}", *r); + } + }, +<<<<<<< HEAD +<<<<<<< HEAD + #[rustfmt::skip] + None => { +======= + None => { + // this comment prevents rustfmt from collapsing the block +>>>>>>> 1c277d1be (Unit tests highlighting unsafe match issue) +======= + #[rustfmt::skip] + None => { +>>>>>>> 9fd34e0c7 (Use #[rustfmt::skip]) + unsafe { + let v = 0; + let r = &v as *const i32; + println!("{}", *r); + } + }, + } +} diff --git a/tests/ui/single_match_else.stderr b/tests/ui/single_match_else.stderr index 62876a55dc61..ddfd7e5993a2 100644 --- a/tests/ui/single_match_else.stderr +++ b/tests/ui/single_match_else.stderr @@ -12,7 +12,7 @@ LL | | }; | |_____^ | = note: `-D clippy::single-match-else` implied by `-D warnings` -help: try this +help: try | LL ~ let _ = if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else { LL + let x = 5; @@ -32,7 +32,7 @@ LL | | }, LL | | } | |_____^ | -help: try this +help: try | LL ~ if let Some(a) = Some(1) { println!("${:?}", a) } else { LL + println!("else block"); @@ -52,7 +52,7 @@ LL | | }, LL | | } | |_____^ | -help: try this +help: try | LL ~ if let Some(a) = Some(1) { println!("${:?}", a) } else { LL + println!("else block"); @@ -72,7 +72,7 @@ LL | | } LL | | } | |_____^ | -help: try this +help: try | LL ~ if let Ok(a) = Result::::Ok(1) { println!("${:?}", a) } else { LL + println!("else block"); @@ -92,7 +92,7 @@ LL | | } LL | | } | |_____^ | -help: try this +help: try | LL ~ if let Cow::Owned(a) = Cow::from("moo") { println!("${:?}", a) } else { LL + println!("else block"); @@ -100,5 +100,118 @@ LL + return; LL + } | -error: aborting due to 5 previous errors +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> $DIR/single_match_else.rs:120:5 + | +LL | / match bar { +LL | | Some(v) => unsafe { +LL | | let r = &v as *const i32; +LL | | println!("{}", *r); +... | +LL | | }, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { unsafe { +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } } else { +LL + println!("None1"); +LL + println!("None2"); +LL + } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> $DIR/single_match_else.rs:131:5 + | +LL | / match bar { +LL | | Some(v) => { +LL | | println!("Some"); +LL | | println!("{v}"); +... | +LL | | }, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { +LL + println!("Some"); +LL + println!("{v}"); +LL + } else { unsafe { +LL + let v = 0; +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> $DIR/single_match_else.rs:143:5 + | +LL | / match bar { +LL | | Some(v) => unsafe { +LL | | let r = &v as *const i32; +LL | | println!("{}", *r); +... | +LL | | }, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { unsafe { +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } } else { unsafe { +LL + let v = 0; +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } } + | + +error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` + --> $DIR/single_match_else.rs:155:5 + | +LL | / match bar { +<<<<<<< HEAD +<<<<<<< HEAD +LL | | #[rustfmt::skip] +LL | | Some(v) => { +======= +LL | | Some(v) => { +LL | | // this comment prevents rustfmt from collapsing the block +>>>>>>> e92614818 (Fix unsafe blocks) +======= +LL | | #[rustfmt::skip] +LL | | Some(v) => { +>>>>>>> 9fd34e0c7 (Use #[rustfmt::skip]) +LL | | unsafe { +... | +LL | | }, +LL | | } + | |_____^ + | +help: try + | +LL ~ if let Some(v) = bar { +<<<<<<< HEAD +<<<<<<< HEAD +======= +LL + // this comment prevents rustfmt from collapsing the block +>>>>>>> e92614818 (Fix unsafe blocks) +======= +>>>>>>> 9fd34e0c7 (Use #[rustfmt::skip]) +LL + unsafe { +LL + let r = &v as *const i32; +LL + println!("{}", *r); +LL + } +LL + } else { +LL + println!("None"); +LL + println!("None"); +LL + } + | + +error: aborting due to 9 previous errors diff --git a/tests/ui/single_range_in_vec_init.rs b/tests/ui/single_range_in_vec_init.rs new file mode 100644 index 000000000000..1f83f294a820 --- /dev/null +++ b/tests/ui/single_range_in_vec_init.rs @@ -0,0 +1,76 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= +//@aux-build:proc_macros.rs:proc-macro +>>>>>>> 5bd97ac17 (Update tests) +#![allow(clippy::no_effect, clippy::useless_vec, unused)] +#![warn(clippy::single_range_in_vec_init)] +#![feature(generic_arg_infer)] + +#[macro_use] +extern crate proc_macros; + +macro_rules! a { + () => { + vec![0..200]; + }; +} + +fn awa(start: T, end: T) { + [start..end]; +} + +fn awa_vec(start: T, end: T) { + vec![start..end]; +} + +fn main() { + // Lint + [0..200]; + vec![0..200]; + [0u8..200]; + [0usize..200]; + [0..200usize]; + vec![0u8..200]; + vec![0usize..200]; + vec![0..200usize]; + // Only suggest collect + [0..200isize]; + vec![0..200isize]; + // Do not lint + [0..200, 0..100]; + vec![0..200, 0..100]; + [0.0..200.0]; + vec![0.0..200.0]; + // `Copy` is not implemented for `Range`, so this doesn't matter +<<<<<<< HEAD +<<<<<<< HEAD + // FIXME: [0..200; 2]; + // FIXME: [vec!0..200; 2]; +======= + // [0..200; 2]; + // [vec!0..200; 2]; +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= + // FIXME: [0..200; 2]; + // FIXME: [vec!0..200; 2]; +>>>>>>> 5bd97ac17 (Update tests) + + // Unfortunately skips any macros + a!(); + + // Skip external macros and procedural macros + external! { + [0..200]; + vec![0..200]; + } + with_span! { + span + [0..200]; + vec![0..200]; + } +} diff --git a/tests/ui/single_range_in_vec_init.stderr b/tests/ui/single_range_in_vec_init.stderr new file mode 100644 index 000000000000..2882980e78f0 --- /dev/null +++ b/tests/ui/single_range_in_vec_init.stderr @@ -0,0 +1,225 @@ +error: an array of `Range` that is only one element + --> $DIR/single_range_in_vec_init.rs:25:5 + | +LL | [0..200]; + | ^^^^^^^^ + | + = note: `-D clippy::single-range-in-vec-init` implied by `-D warnings` +<<<<<<< HEAD +<<<<<<< HEAD +help: if you wanted a `Vec` that contains the entire range, try +======= +help: if you wanted a `Vec` that contains every value in the range, try +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= +help: if you wanted a `Vec` that contains the entire range, try +>>>>>>> 830d307d0 (refactor a bit) + | +LL | (0..200).collect::>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: if you wanted an array of len 200, try + | +LL | [0; 200]; + | ~~~~~~ + +error: a `Vec` of `Range` that is only one element + --> $DIR/single_range_in_vec_init.rs:26:5 + | +LL | vec![0..200]; + | ^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD +help: if you wanted a `Vec` that contains the entire range, try +======= +help: if you wanted a `Vec` that contains every value in the range, try +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= +help: if you wanted a `Vec` that contains the entire range, try +>>>>>>> 830d307d0 (refactor a bit) + | +LL | (0..200).collect::>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: if you wanted a `Vec` of len 200, try + | +LL | vec![0; 200]; + | ~~~~~~ + +error: an array of `Range` that is only one element + --> $DIR/single_range_in_vec_init.rs:27:5 + | +LL | [0u8..200]; + | ^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD +help: if you wanted a `Vec` that contains the entire range, try +======= +help: if you wanted a `Vec` that contains every value in the range, try +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= +help: if you wanted a `Vec` that contains the entire range, try +>>>>>>> 830d307d0 (refactor a bit) + | +LL | (0u8..200).collect::>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: if you wanted an array of len 200, try + | +LL | [0u8; 200]; + | ~~~~~~~~ + +error: an array of `Range` that is only one element + --> $DIR/single_range_in_vec_init.rs:28:5 + | +LL | [0usize..200]; + | ^^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD +help: if you wanted a `Vec` that contains the entire range, try +======= +help: if you wanted a `Vec` that contains every value in the range, try +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= +help: if you wanted a `Vec` that contains the entire range, try +>>>>>>> 830d307d0 (refactor a bit) + | +LL | (0usize..200).collect::>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: if you wanted an array of len 200, try + | +LL | [0usize; 200]; + | ~~~~~~~~~~~ + +error: an array of `Range` that is only one element + --> $DIR/single_range_in_vec_init.rs:29:5 + | +LL | [0..200usize]; + | ^^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD +help: if you wanted a `Vec` that contains the entire range, try +======= +help: if you wanted a `Vec` that contains every value in the range, try +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= +help: if you wanted a `Vec` that contains the entire range, try +>>>>>>> 830d307d0 (refactor a bit) + | +LL | (0..200usize).collect::>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: if you wanted an array of len 200usize, try + | +LL | [0; 200usize]; + | ~~~~~~~~~~~ + +error: a `Vec` of `Range` that is only one element + --> $DIR/single_range_in_vec_init.rs:30:5 + | +LL | vec![0u8..200]; + | ^^^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD +help: if you wanted a `Vec` that contains the entire range, try +======= +help: if you wanted a `Vec` that contains every value in the range, try +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= +help: if you wanted a `Vec` that contains the entire range, try +>>>>>>> 830d307d0 (refactor a bit) + | +LL | (0u8..200).collect::>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: if you wanted a `Vec` of len 200, try + | +LL | vec![0u8; 200]; + | ~~~~~~~~ + +error: a `Vec` of `Range` that is only one element + --> $DIR/single_range_in_vec_init.rs:31:5 + | +LL | vec![0usize..200]; + | ^^^^^^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD +help: if you wanted a `Vec` that contains the entire range, try +======= +help: if you wanted a `Vec` that contains every value in the range, try +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= +help: if you wanted a `Vec` that contains the entire range, try +>>>>>>> 830d307d0 (refactor a bit) + | +LL | (0usize..200).collect::>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: if you wanted a `Vec` of len 200, try + | +LL | vec![0usize; 200]; + | ~~~~~~~~~~~ + +error: a `Vec` of `Range` that is only one element + --> $DIR/single_range_in_vec_init.rs:32:5 + | +LL | vec![0..200usize]; + | ^^^^^^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD +help: if you wanted a `Vec` that contains the entire range, try +======= +help: if you wanted a `Vec` that contains every value in the range, try +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= +help: if you wanted a `Vec` that contains the entire range, try +>>>>>>> 830d307d0 (refactor a bit) + | +LL | (0..200usize).collect::>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: if you wanted a `Vec` of len 200usize, try + | +LL | vec![0; 200usize]; + | ~~~~~~~~~~~ + +error: an array of `Range` that is only one element + --> $DIR/single_range_in_vec_init.rs:34:5 + | +LL | [0..200isize]; + | ^^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD +help: if you wanted a `Vec` that contains the entire range, try +======= +help: if you wanted a `Vec` that contains every value in the range, try +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= +help: if you wanted a `Vec` that contains the entire range, try +>>>>>>> 830d307d0 (refactor a bit) + | +LL | (0..200isize).collect::>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: a `Vec` of `Range` that is only one element + --> $DIR/single_range_in_vec_init.rs:35:5 + | +LL | vec![0..200isize]; + | ^^^^^^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD +help: if you wanted a `Vec` that contains the entire range, try +======= +help: if you wanted a `Vec` that contains every value in the range, try +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) +======= +help: if you wanted a `Vec` that contains the entire range, try +>>>>>>> 830d307d0 (refactor a bit) + | +LL | (0..200isize).collect::>(); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 10 previous errors + diff --git a/tests/ui/skip_while_next.rs b/tests/ui/skip_while_next.rs index a551c19d98bc..8e4cd82cec30 100644 --- a/tests/ui/skip_while_next.rs +++ b/tests/ui/skip_while_next.rs @@ -1,7 +1,7 @@ -// aux-build:option_helpers.rs +//@aux-build:option_helpers.rs #![warn(clippy::skip_while_next)] -#![allow(clippy::disallowed_names)] +#![allow(clippy::disallowed_names, clippy::useless_vec)] extern crate option_helpers; use option_helpers::IteratorFalsePositives; diff --git a/tests/ui/slow_vector_initialization.stderr b/tests/ui/slow_vector_initialization.stderr index cb3ce3e95a7a..22376680a8e6 100644 --- a/tests/ui/slow_vector_initialization.stderr +++ b/tests/ui/slow_vector_initialization.stderr @@ -72,5 +72,13 @@ LL | vec1 = Vec::with_capacity(10); LL | vec1.resize(10, 0); | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error: this argument is a mutable reference, but not used mutably + --> $DIR/slow_vector_initialization.rs:62:18 + | +LL | fn do_stuff(vec: &mut [u8]) {} + | ^^^^^^^^^ help: consider changing to: `&[u8]` + | + = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` + +error: aborting due to 10 previous errors diff --git a/tests/ui/stable_sort_primitive.fixed b/tests/ui/stable_sort_primitive.fixed index f5f18169df29..50c1fc71a3f9 100644 --- a/tests/ui/stable_sort_primitive.fixed +++ b/tests/ui/stable_sort_primitive.fixed @@ -1,5 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::stable_sort_primitive)] +#![allow(clippy::useless_vec)] fn main() { // positive examples diff --git a/tests/ui/stable_sort_primitive.rs b/tests/ui/stable_sort_primitive.rs index 8149c5638e0f..bd1bb428f2bb 100644 --- a/tests/ui/stable_sort_primitive.rs +++ b/tests/ui/stable_sort_primitive.rs @@ -1,5 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::stable_sort_primitive)] +#![allow(clippy::useless_vec)] fn main() { // positive examples diff --git a/tests/ui/stable_sort_primitive.stderr b/tests/ui/stable_sort_primitive.stderr index 1432fdcff77a..aa5d7b7e4914 100644 --- a/tests/ui/stable_sort_primitive.stderr +++ b/tests/ui/stable_sort_primitive.stderr @@ -1,5 +1,5 @@ error: used `sort` on primitive type `i32` - --> $DIR/stable_sort_primitive.rs:7:5 + --> $DIR/stable_sort_primitive.rs:8:5 | LL | vec.sort(); | ^^^^^^^^^^ help: try: `vec.sort_unstable()` @@ -8,7 +8,7 @@ LL | vec.sort(); = note: `-D clippy::stable-sort-primitive` implied by `-D warnings` error: used `sort` on primitive type `bool` - --> $DIR/stable_sort_primitive.rs:9:5 + --> $DIR/stable_sort_primitive.rs:10:5 | LL | vec.sort(); | ^^^^^^^^^^ help: try: `vec.sort_unstable()` @@ -16,7 +16,7 @@ LL | vec.sort(); = note: an unstable sort typically performs faster without any observable difference for this data type error: used `sort` on primitive type `char` - --> $DIR/stable_sort_primitive.rs:11:5 + --> $DIR/stable_sort_primitive.rs:12:5 | LL | vec.sort(); | ^^^^^^^^^^ help: try: `vec.sort_unstable()` @@ -24,7 +24,7 @@ LL | vec.sort(); = note: an unstable sort typically performs faster without any observable difference for this data type error: used `sort` on primitive type `str` - --> $DIR/stable_sort_primitive.rs:13:5 + --> $DIR/stable_sort_primitive.rs:14:5 | LL | vec.sort(); | ^^^^^^^^^^ help: try: `vec.sort_unstable()` @@ -32,7 +32,7 @@ LL | vec.sort(); = note: an unstable sort typically performs faster without any observable difference for this data type error: used `sort` on primitive type `tuple` - --> $DIR/stable_sort_primitive.rs:15:5 + --> $DIR/stable_sort_primitive.rs:16:5 | LL | vec.sort(); | ^^^^^^^^^^ help: try: `vec.sort_unstable()` @@ -40,7 +40,7 @@ LL | vec.sort(); = note: an unstable sort typically performs faster without any observable difference for this data type error: used `sort` on primitive type `array` - --> $DIR/stable_sort_primitive.rs:17:5 + --> $DIR/stable_sort_primitive.rs:18:5 | LL | vec.sort(); | ^^^^^^^^^^ help: try: `vec.sort_unstable()` @@ -48,7 +48,7 @@ LL | vec.sort(); = note: an unstable sort typically performs faster without any observable difference for this data type error: used `sort` on primitive type `i32` - --> $DIR/stable_sort_primitive.rs:19:5 + --> $DIR/stable_sort_primitive.rs:20:5 | LL | arr.sort(); | ^^^^^^^^^^ help: try: `arr.sort_unstable()` diff --git a/tests/ui/starts_ends_with.fixed b/tests/ui/starts_ends_with.fixed index 983fac7afe69..d62e12a6f973 100644 --- a/tests/ui/starts_ends_with.fixed +++ b/tests/ui/starts_ends_with.fixed @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(clippy::needless_if, dead_code, unused_must_use)] +======= #![allow(dead_code, unused_must_use)] +>>>>>>> e4f5d83fa (Fixed formatting.) fn main() {} diff --git a/tests/ui/starts_ends_with.rs b/tests/ui/starts_ends_with.rs index e3335dd2e2ef..36de2e6240fb 100644 --- a/tests/ui/starts_ends_with.rs +++ b/tests/ui/starts_ends_with.rs @@ -1,5 +1,9 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +#![allow(clippy::needless_if, dead_code, unused_must_use)] +======= #![allow(dead_code, unused_must_use)] +>>>>>>> e4f5d83fa (Fixed formatting.) fn main() {} diff --git a/tests/ui/string_add.rs b/tests/ui/string_add.rs index 20edbe31fa9e..1431cc8e6e12 100644 --- a/tests/ui/string_add.rs +++ b/tests/ui/string_add.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) extern crate proc_macros; use proc_macros::external; diff --git a/tests/ui/string_add_assign.fixed b/tests/ui/string_add_assign.fixed index b687f43b2541..616c6daaf660 100644 --- a/tests/ui/string_add_assign.fixed +++ b/tests/ui/string_add_assign.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[allow(clippy::string_add, unused)] #[warn(clippy::string_add_assign)] diff --git a/tests/ui/string_add_assign.rs b/tests/ui/string_add_assign.rs index e5dbde108fbd..e1f8859757c6 100644 --- a/tests/ui/string_add_assign.rs +++ b/tests/ui/string_add_assign.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[allow(clippy::string_add, unused)] #[warn(clippy::string_add_assign)] diff --git a/tests/ui/string_extend.fixed b/tests/ui/string_extend.fixed index d200d7310fca..65c9abff3d41 100644 --- a/tests/ui/string_extend.fixed +++ b/tests/ui/string_extend.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[derive(Copy, Clone)] struct HasChars; diff --git a/tests/ui/string_extend.rs b/tests/ui/string_extend.rs index 0dd96a3b2103..5f72ffe2fda7 100644 --- a/tests/ui/string_extend.rs +++ b/tests/ui/string_extend.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[derive(Copy, Clone)] struct HasChars; diff --git a/tests/ui/string_extend.stderr b/tests/ui/string_extend.stderr index b35c77fd9611..34b43290147e 100644 --- a/tests/ui/string_extend.stderr +++ b/tests/ui/string_extend.stderr @@ -2,7 +2,7 @@ error: calling `.extend(_.chars())` --> $DIR/string_extend.rs:18:5 | LL | s.extend(abc.chars()); - | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.push_str(abc)` + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(abc)` | = note: `-D clippy::string-extend-chars` implied by `-D warnings` @@ -10,19 +10,19 @@ error: calling `.extend(_.chars())` --> $DIR/string_extend.rs:21:5 | LL | s.extend("abc".chars()); - | ^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.push_str("abc")` + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str("abc")` error: calling `.extend(_.chars())` --> $DIR/string_extend.rs:24:5 | LL | s.extend(def.chars()); - | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.push_str(&def)` + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(&def)` error: calling `.extend(_.chars())` --> $DIR/string_extend.rs:34:5 | LL | s.extend(abc[0..2].chars()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.push_str(&abc[0..2])` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(&abc[0..2])` error: aborting due to 4 previous errors diff --git a/tests/ui/string_from_utf8_as_bytes.fixed b/tests/ui/string_from_utf8_as_bytes.fixed index 6e665cdd5630..9b315ae2b558 100644 --- a/tests/ui/string_from_utf8_as_bytes.fixed +++ b/tests/ui/string_from_utf8_as_bytes.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::string_from_utf8_as_bytes)] fn main() { diff --git a/tests/ui/string_from_utf8_as_bytes.rs b/tests/ui/string_from_utf8_as_bytes.rs index 670d206d3679..043dd2350829 100644 --- a/tests/ui/string_from_utf8_as_bytes.rs +++ b/tests/ui/string_from_utf8_as_bytes.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::string_from_utf8_as_bytes)] fn main() { diff --git a/tests/ui/string_lit_as_bytes.fixed b/tests/ui/string_lit_as_bytes.fixed index 506187fc1257..39369360a56d 100644 --- a/tests/ui/string_lit_as_bytes.fixed +++ b/tests/ui/string_lit_as_bytes.fixed @@ -1,8 +1,48 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:macro_rules.rs +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +//@aux-build:macro_rules.rs +>>>>>>> 14a6fa4a3 (use in_external_macro) -#![allow(dead_code, unused_variables)] +#![allow(clippy::needless_raw_string_hashes, dead_code, unused_variables)] #![warn(clippy::string_lit_as_bytes)] +<<<<<<< HEAD +<<<<<<< HEAD +#[macro_use] +extern crate macro_rules; + +macro_rules! b { + ($b:literal) => { + const B: &[u8] = b"warning"; + }; +======= +macro_rules! b { + ($b:literal) => { + const C: &[u8] = $b.as_bytes(); +<<<<<<< HEAD + } +>>>>>>> acfb2c45b (don't check if from macro invocation) +======= +======= +#[macro_use] +extern crate macro_rules; + +macro_rules! b { + ($b:literal) => { + const B: &[u8] = b"warning"; +>>>>>>> 14a6fa4a3 (use in_external_macro) + }; +>>>>>>> 1ac30d3c8 (make cargo test pass) +} + fn str_lit_as_bytes() { let bs = b"hello there"; @@ -11,6 +51,20 @@ fn str_lit_as_bytes() { let bs = b"lit to string".to_vec(); let bs = b"lit to owned".to_vec(); +<<<<<<< HEAD +<<<<<<< HEAD + b!("warning"); + + string_lit_as_bytes!("no warning"); +======= + b!("aaa"); +>>>>>>> acfb2c45b (don't check if from macro invocation) +======= + b!("warning"); + + string_lit_as_bytes!("no warning"); +>>>>>>> 14a6fa4a3 (use in_external_macro) + // no warning, because these cannot be written as byte string literals: let ubs = "☃".as_bytes(); let ubs = "hello there! this is a very long string".as_bytes(); diff --git a/tests/ui/string_lit_as_bytes.rs b/tests/ui/string_lit_as_bytes.rs index 2c339f1ddb81..0db3c4d78b4f 100644 --- a/tests/ui/string_lit_as_bytes.rs +++ b/tests/ui/string_lit_as_bytes.rs @@ -1,8 +1,48 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@aux-build:macro_rules.rs +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +//@aux-build:macro_rules.rs +>>>>>>> 14a6fa4a3 (use in_external_macro) -#![allow(dead_code, unused_variables)] +#![allow(clippy::needless_raw_string_hashes, dead_code, unused_variables)] #![warn(clippy::string_lit_as_bytes)] +<<<<<<< HEAD +<<<<<<< HEAD +#[macro_use] +extern crate macro_rules; + +macro_rules! b { + ($b:literal) => { + const B: &[u8] = $b.as_bytes(); + }; +======= +macro_rules! b { + ($b:literal) => { + const C: &[u8] = $b.as_bytes(); +<<<<<<< HEAD + } +>>>>>>> acfb2c45b (don't check if from macro invocation) +======= +======= +#[macro_use] +extern crate macro_rules; + +macro_rules! b { + ($b:literal) => { + const B: &[u8] = $b.as_bytes(); +>>>>>>> 14a6fa4a3 (use in_external_macro) + }; +>>>>>>> 8efe9ff9f (run cargo dev fmt) +} + fn str_lit_as_bytes() { let bs = "hello there".as_bytes(); @@ -11,6 +51,20 @@ fn str_lit_as_bytes() { let bs = "lit to string".to_string().into_bytes(); let bs = "lit to owned".to_owned().into_bytes(); +<<<<<<< HEAD +<<<<<<< HEAD + b!("warning"); + + string_lit_as_bytes!("no warning"); +======= + b!("aaa"); +>>>>>>> acfb2c45b (don't check if from macro invocation) +======= + b!("warning"); + + string_lit_as_bytes!("no warning"); +>>>>>>> 14a6fa4a3 (use in_external_macro) + // no warning, because these cannot be written as byte string literals: let ubs = "☃".as_bytes(); let ubs = "hello there! this is a very long string".as_bytes(); diff --git a/tests/ui/string_lit_as_bytes.stderr b/tests/ui/string_lit_as_bytes.stderr index f47d6161c6cf..5da1e3d44881 100644 --- a/tests/ui/string_lit_as_bytes.stderr +++ b/tests/ui/string_lit_as_bytes.stderr @@ -1,5 +1,13 @@ error: calling `as_bytes()` on a string literal - --> $DIR/string_lit_as_bytes.rs:7:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/string_lit_as_bytes.rs:17:14 +======= + --> $DIR/string_lit_as_bytes.rs:13:14 +>>>>>>> acfb2c45b (don't check if from macro invocation) +======= + --> $DIR/string_lit_as_bytes.rs:17:14 +>>>>>>> 14a6fa4a3 (use in_external_macro) | LL | let bs = "hello there".as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"hello there"` @@ -7,34 +15,85 @@ LL | let bs = "hello there".as_bytes(); = note: `-D clippy::string-lit-as-bytes` implied by `-D warnings` error: calling `as_bytes()` on a string literal - --> $DIR/string_lit_as_bytes.rs:9:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/string_lit_as_bytes.rs:19:14 +======= + --> $DIR/string_lit_as_bytes.rs:15:14 +>>>>>>> acfb2c45b (don't check if from macro invocation) +======= + --> $DIR/string_lit_as_bytes.rs:19:14 +>>>>>>> 14a6fa4a3 (use in_external_macro) | LL | let bs = r###"raw string with 3# plus " ""###.as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `br###"raw string with 3# plus " ""###` error: calling `into_bytes()` on a string literal - --> $DIR/string_lit_as_bytes.rs:11:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/string_lit_as_bytes.rs:21:14 +======= + --> $DIR/string_lit_as_bytes.rs:17:14 +>>>>>>> acfb2c45b (don't check if from macro invocation) +======= + --> $DIR/string_lit_as_bytes.rs:21:14 +>>>>>>> 14a6fa4a3 (use in_external_macro) | LL | let bs = "lit to string".to_string().into_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to string".to_vec()` error: calling `into_bytes()` on a string literal - --> $DIR/string_lit_as_bytes.rs:12:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/string_lit_as_bytes.rs:22:14 +======= + --> $DIR/string_lit_as_bytes.rs:18:14 +>>>>>>> acfb2c45b (don't check if from macro invocation) +======= + --> $DIR/string_lit_as_bytes.rs:22:14 +>>>>>>> 14a6fa4a3 (use in_external_macro) | LL | let bs = "lit to owned".to_owned().into_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to owned".to_vec()` +error: calling `as_bytes()` on a string literal + --> $DIR/string_lit_as_bytes.rs:12:26 + | +LL | const B: &[u8] = $b.as_bytes(); + | ^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"warning"` +... +LL | b!("warning"); + | ------------- in this macro invocation + | + = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) + error: calling `as_bytes()` on `include_str!(..)` - --> $DIR/string_lit_as_bytes.rs:25:22 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/string_lit_as_bytes.rs:39:22 +======= + --> $DIR/string_lit_as_bytes.rs:33:22 +>>>>>>> acfb2c45b (don't check if from macro invocation) +======= + --> $DIR/string_lit_as_bytes.rs:39:22 +>>>>>>> 14a6fa4a3 (use in_external_macro) | LL | let includestr = include_str!("string_lit_as_bytes.rs").as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("string_lit_as_bytes.rs")` error: calling `as_bytes()` on a string literal - --> $DIR/string_lit_as_bytes.rs:27:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/string_lit_as_bytes.rs:41:13 +======= + --> $DIR/string_lit_as_bytes.rs:35:13 +>>>>>>> acfb2c45b (don't check if from macro invocation) +======= + --> $DIR/string_lit_as_bytes.rs:41:13 +>>>>>>> 14a6fa4a3 (use in_external_macro) | LL | let _ = "string with newline/t/n".as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"string with newline/t/n"` -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors diff --git a/tests/ui/strlen_on_c_strings.fixed b/tests/ui/strlen_on_c_strings.fixed index 947a59bcc027..ef207e28cca3 100644 --- a/tests/ui/strlen_on_c_strings.fixed +++ b/tests/ui/strlen_on_c_strings.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::strlen_on_c_strings)] #![allow(dead_code)] diff --git a/tests/ui/strlen_on_c_strings.rs b/tests/ui/strlen_on_c_strings.rs index 1237f1ab03ac..03ec5f79d092 100644 --- a/tests/ui/strlen_on_c_strings.rs +++ b/tests/ui/strlen_on_c_strings.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::strlen_on_c_strings)] #![allow(dead_code)] diff --git a/tests/ui/strlen_on_c_strings.stderr b/tests/ui/strlen_on_c_strings.stderr index 296268a5f1df..fcd17f689404 100644 --- a/tests/ui/strlen_on_c_strings.stderr +++ b/tests/ui/strlen_on_c_strings.stderr @@ -2,7 +2,7 @@ error: using `libc::strlen` on a `CString` or `CStr` value --> $DIR/strlen_on_c_strings.rs:15:13 | LL | let _ = unsafe { libc::strlen(cstring.as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `cstring.as_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstring.as_bytes().len()` | = note: `-D clippy::strlen-on-c-strings` implied by `-D warnings` @@ -10,37 +10,37 @@ error: using `libc::strlen` on a `CString` or `CStr` value --> $DIR/strlen_on_c_strings.rs:19:13 | LL | let _ = unsafe { libc::strlen(cstr.as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `cstr.to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value --> $DIR/strlen_on_c_strings.rs:21:13 | LL | let _ = unsafe { strlen(cstr.as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `cstr.to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value --> $DIR/strlen_on_c_strings.rs:24:22 | LL | let _ = unsafe { strlen((*pcstr).as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `(*pcstr).to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*pcstr).to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value --> $DIR/strlen_on_c_strings.rs:29:22 | LL | let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unsafe_identity(cstr).to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe_identity(cstr).to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value --> $DIR/strlen_on_c_strings.rs:30:13 | LL | let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unsafe { unsafe_identity(cstr) }.to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe { unsafe_identity(cstr) }.to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value --> $DIR/strlen_on_c_strings.rs:33:22 | LL | let _ = unsafe { strlen(f(cstr).as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `f(cstr).to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `f(cstr).to_bytes().len()` error: aborting due to 7 previous errors diff --git a/tests/ui/suspicious_doc_comments.fixed b/tests/ui/suspicious_doc_comments.fixed index b404df94d3c2..9a23a11fe083 100644 --- a/tests/ui/suspicious_doc_comments.fixed +++ b/tests/ui/suspicious_doc_comments.fixed @@ -1,4 +1,16 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= // run-rustfix +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +//@run-rustfix +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +//@run-rustfix +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) #![allow(unused)] #![warn(clippy::suspicious_doc_comments)] diff --git a/tests/ui/suspicious_doc_comments.rs b/tests/ui/suspicious_doc_comments.rs index 46eff51e220f..e7e0ff8176ad 100644 --- a/tests/ui/suspicious_doc_comments.rs +++ b/tests/ui/suspicious_doc_comments.rs @@ -1,4 +1,16 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +======= // run-rustfix +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +//@run-rustfix +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +//@run-rustfix +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) #![allow(unused)] #![warn(clippy::suspicious_doc_comments)] diff --git a/tests/ui/suspicious_else_formatting.rs b/tests/ui/suspicious_else_formatting.rs index 21753e5dc6a4..8ffffd62e3f0 100644 --- a/tests/ui/suspicious_else_formatting.rs +++ b/tests/ui/suspicious_else_formatting.rs @@ -1,7 +1,26 @@ -// aux-build:proc_macro_suspicious_else_formatting.rs +<<<<<<< HEAD +//@aux-build:proc_macro_suspicious_else_formatting.rs:proc-macro +======= +//@aux-build:proc_macro_suspicious_else_formatting.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::suspicious_else_formatting)] -#![allow(clippy::if_same_then_else, clippy::let_unit_value)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 26f50395b (Add `needless_if` lint) +#![allow( + clippy::if_same_then_else, + clippy::let_unit_value, + clippy::needless_if, + clippy::needless_else +)] +<<<<<<< HEAD +======= +#![allow(clippy::if_same_then_else, clippy::let_unit_value, clippy::needless_else)] +>>>>>>> e6646eb5f (needless_else: new lint to check for empty else clauses) +======= +>>>>>>> 26f50395b (Add `needless_if` lint) extern crate proc_macro_suspicious_else_formatting; use proc_macro_suspicious_else_formatting::DeriveBadSpan; @@ -108,6 +127,13 @@ fn main() { else { } + + //#10273 This is fine. Don't warn + if foo() { + } else + /* whelp */ + { + } } // #7650 - Don't lint. Proc-macro using bad spans for `if` expressions. diff --git a/tests/ui/suspicious_else_formatting.stderr b/tests/ui/suspicious_else_formatting.stderr index 2e512b47f123..723fdd7e93e3 100644 --- a/tests/ui/suspicious_else_formatting.stderr +++ b/tests/ui/suspicious_else_formatting.stderr @@ -1,5 +1,5 @@ error: this looks like an `else {..}` but the `else` is missing - --> $DIR/suspicious_else_formatting.rs:17:6 + --> $DIR/suspicious_else_formatting.rs:22:6 | LL | } { | ^ @@ -8,7 +8,7 @@ LL | } { = note: `-D clippy::suspicious-else-formatting` implied by `-D warnings` error: this looks like an `else if` but the `else` is missing - --> $DIR/suspicious_else_formatting.rs:21:6 + --> $DIR/suspicious_else_formatting.rs:26:6 | LL | } if foo() { | ^ @@ -16,7 +16,7 @@ LL | } if foo() { = note: to remove this lint, add the missing `else` or add a new line before the second `if` error: this looks like an `else if` but the `else` is missing - --> $DIR/suspicious_else_formatting.rs:28:10 + --> $DIR/suspicious_else_formatting.rs:33:10 | LL | } if foo() { | ^ @@ -24,7 +24,7 @@ LL | } if foo() { = note: to remove this lint, add the missing `else` or add a new line before the second `if` error: this looks like an `else if` but the `else` is missing - --> $DIR/suspicious_else_formatting.rs:36:10 + --> $DIR/suspicious_else_formatting.rs:41:10 | LL | } if foo() { | ^ @@ -32,7 +32,7 @@ LL | } if foo() { = note: to remove this lint, add the missing `else` or add a new line before the second `if` error: this is an `else {..}` but the formatting might hide it - --> $DIR/suspicious_else_formatting.rs:45:6 + --> $DIR/suspicious_else_formatting.rs:50:6 | LL | } else | ______^ @@ -42,7 +42,7 @@ LL | | { = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}` error: this is an `else if` but the formatting might hide it - --> $DIR/suspicious_else_formatting.rs:57:6 + --> $DIR/suspicious_else_formatting.rs:62:6 | LL | } else | ______^ @@ -52,7 +52,7 @@ LL | | if foo() { // the span of the above error should continue here = note: to remove this lint, remove the `else` or remove the new line between `else` and `if` error: this is an `else if` but the formatting might hide it - --> $DIR/suspicious_else_formatting.rs:62:6 + --> $DIR/suspicious_else_formatting.rs:67:6 | LL | } | ______^ @@ -63,7 +63,7 @@ LL | | if foo() { // the span of the above error should continue here = note: to remove this lint, remove the `else` or remove the new line between `else` and `if` error: this is an `else {..}` but the formatting might hide it - --> $DIR/suspicious_else_formatting.rs:89:6 + --> $DIR/suspicious_else_formatting.rs:94:6 | LL | } | ______^ @@ -75,7 +75,7 @@ LL | | { = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}` error: this is an `else {..}` but the formatting might hide it - --> $DIR/suspicious_else_formatting.rs:97:6 + --> $DIR/suspicious_else_formatting.rs:102:6 | LL | } | ______^ diff --git a/tests/ui/suspicious_operation_groupings.fixed b/tests/ui/suspicious_operation_groupings.fixed index ede8a39fed71..0e37701ec48b 100644 --- a/tests/ui/suspicious_operation_groupings.fixed +++ b/tests/ui/suspicious_operation_groupings.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suspicious_operation_groupings)] #![allow(dead_code, unused_parens, clippy::eq_op)] diff --git a/tests/ui/suspicious_operation_groupings.rs b/tests/ui/suspicious_operation_groupings.rs index 26ce97bb37f8..dd4f3b71c378 100644 --- a/tests/ui/suspicious_operation_groupings.rs +++ b/tests/ui/suspicious_operation_groupings.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suspicious_operation_groupings)] #![allow(dead_code, unused_parens, clippy::eq_op)] diff --git a/tests/ui/suspicious_unary_op_formatting.rs b/tests/ui/suspicious_unary_op_formatting.rs index 9564e373c246..3c5ca1762fe4 100644 --- a/tests/ui/suspicious_unary_op_formatting.rs +++ b/tests/ui/suspicious_unary_op_formatting.rs @@ -1,4 +1,5 @@ #![warn(clippy::suspicious_unary_op_formatting)] +#![allow(clippy::needless_if)] #[rustfmt::skip] fn main() { diff --git a/tests/ui/suspicious_unary_op_formatting.stderr b/tests/ui/suspicious_unary_op_formatting.stderr index 9f1289ccba0c..52b0e99a1d3e 100644 --- a/tests/ui/suspicious_unary_op_formatting.stderr +++ b/tests/ui/suspicious_unary_op_formatting.stderr @@ -1,5 +1,5 @@ error: by not having a space between `>` and `-` it looks like `>-` is a single operator - --> $DIR/suspicious_unary_op_formatting.rs:8:9 + --> $DIR/suspicious_unary_op_formatting.rs:9:9 | LL | if a >- 30 {} | ^^^^ @@ -8,7 +8,7 @@ LL | if a >- 30 {} = note: `-D clippy::suspicious-unary-op-formatting` implied by `-D warnings` error: by not having a space between `>=` and `-` it looks like `>=-` is a single operator - --> $DIR/suspicious_unary_op_formatting.rs:9:9 + --> $DIR/suspicious_unary_op_formatting.rs:10:9 | LL | if a >=- 30 {} | ^^^^^ @@ -16,7 +16,7 @@ LL | if a >=- 30 {} = help: put a space between `>=` and `-` and remove the space after `-` error: by not having a space between `&&` and `!` it looks like `&&!` is a single operator - --> $DIR/suspicious_unary_op_formatting.rs:14:9 + --> $DIR/suspicious_unary_op_formatting.rs:15:9 | LL | if b &&! c {} | ^^^^^ @@ -24,7 +24,7 @@ LL | if b &&! c {} = help: put a space between `&&` and `!` and remove the space after `!` error: by not having a space between `>` and `-` it looks like `>-` is a single operator - --> $DIR/suspicious_unary_op_formatting.rs:16:9 + --> $DIR/suspicious_unary_op_formatting.rs:17:9 | LL | if a >- 30 {} | ^^^^^^ diff --git a/tests/ui/swap.fixed b/tests/ui/swap.fixed index 9703674d1a4e..22f904e3fd9e 100644 --- a/tests/ui/swap.fixed +++ b/tests/ui/swap.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build: macro_rules.rs +//@run-rustfix +//@aux-build: macro_rules.rs #![warn(clippy::all)] #![allow( @@ -10,7 +10,8 @@ dead_code, unused_assignments, unused_variables, - clippy::let_and_return + clippy::let_and_return, + clippy::useless_vec )] struct Foo(u32); diff --git a/tests/ui/swap.rs b/tests/ui/swap.rs index a0228065e46b..ada64f89e6d2 100644 --- a/tests/ui/swap.rs +++ b/tests/ui/swap.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build: macro_rules.rs +//@run-rustfix +//@aux-build: macro_rules.rs #![warn(clippy::all)] #![allow( @@ -10,7 +10,8 @@ dead_code, unused_assignments, unused_variables, - clippy::let_and_return + clippy::let_and_return, + clippy::useless_vec )] struct Foo(u32); diff --git a/tests/ui/swap.stderr b/tests/ui/swap.stderr index 0c246268499d..a3b9c2b744c9 100644 --- a/tests/ui/swap.stderr +++ b/tests/ui/swap.stderr @@ -1,5 +1,5 @@ error: this looks like you are swapping `bar.a` and `bar.b` manually - --> $DIR/swap.rs:27:5 + --> $DIR/swap.rs:28:5 | LL | / let temp = bar.a; LL | | bar.a = bar.b; @@ -10,7 +10,7 @@ LL | | bar.b = temp; = note: `-D clippy::manual-swap` implied by `-D warnings` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:39:5 + --> $DIR/swap.rs:40:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -18,7 +18,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:48:5 + --> $DIR/swap.rs:49:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -26,7 +26,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:67:5 + --> $DIR/swap.rs:68:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -34,7 +34,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:78:5 + --> $DIR/swap.rs:79:5 | LL | / a ^= b; LL | | b ^= a; @@ -42,7 +42,7 @@ LL | | a ^= b; | |___________^ help: try: `std::mem::swap(&mut a, &mut b);` error: this looks like you are swapping `bar.a` and `bar.b` manually - --> $DIR/swap.rs:86:5 + --> $DIR/swap.rs:87:5 | LL | / bar.a ^= bar.b; LL | | bar.b ^= bar.a; @@ -50,7 +50,7 @@ LL | | bar.a ^= bar.b; | |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:94:5 + --> $DIR/swap.rs:95:5 | LL | / foo[0] ^= foo[1]; LL | | foo[1] ^= foo[0]; @@ -58,7 +58,7 @@ LL | | foo[0] ^= foo[1]; | |_____________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually - --> $DIR/swap.rs:123:5 + --> $DIR/swap.rs:124:5 | LL | / let temp = foo[0][1]; LL | | foo[0][1] = bar[1][0]; @@ -68,7 +68,7 @@ LL | | bar[1][0] = temp; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:137:7 + --> $DIR/swap.rs:138:7 | LL | ; let t = a; | _______^ @@ -79,7 +79,7 @@ LL | | b = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `c.0` and `a` manually - --> $DIR/swap.rs:146:7 + --> $DIR/swap.rs:147:7 | LL | ; let t = c.0; | _______^ @@ -90,7 +90,7 @@ LL | | a = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `b` and `a` manually - --> $DIR/swap.rs:172:5 + --> $DIR/swap.rs:173:5 | LL | / let t = b; LL | | b = a; @@ -100,7 +100,7 @@ LL | | a = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:134:5 + --> $DIR/swap.rs:135:5 | LL | / a = b; LL | | b = a; @@ -110,7 +110,7 @@ LL | | b = a; = note: `-D clippy::almost-swapped` implied by `-D warnings` error: this looks like you are trying to swap `c.0` and `a` - --> $DIR/swap.rs:143:5 + --> $DIR/swap.rs:144:5 | LL | / c.0 = a; LL | | a = c.0; @@ -119,7 +119,7 @@ LL | | a = c.0; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:150:5 + --> $DIR/swap.rs:151:5 | LL | / let a = b; LL | | let b = a; @@ -128,7 +128,7 @@ LL | | let b = a; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `d` and `c` - --> $DIR/swap.rs:155:5 + --> $DIR/swap.rs:156:5 | LL | / d = c; LL | | c = d; @@ -137,7 +137,7 @@ LL | | c = d; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:159:5 + --> $DIR/swap.rs:160:5 | LL | / let a = b; LL | | b = a; @@ -146,7 +146,7 @@ LL | | b = a; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `s.0.x` and `s.0.y` manually - --> $DIR/swap.rs:207:5 + --> $DIR/swap.rs:208:5 | LL | / let t = s.0.x; LL | | s.0.x = s.0.y; diff --git a/tests/ui/swap_ptr_to_ref.fixed b/tests/ui/swap_ptr_to_ref.fixed index 596b6ee919bb..3bede3017a13 100644 --- a/tests/ui/swap_ptr_to_ref.fixed +++ b/tests/ui/swap_ptr_to_ref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::swap_ptr_to_ref)] diff --git a/tests/ui/swap_ptr_to_ref.rs b/tests/ui/swap_ptr_to_ref.rs index 282f571211d9..726b09d37643 100644 --- a/tests/ui/swap_ptr_to_ref.rs +++ b/tests/ui/swap_ptr_to_ref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::swap_ptr_to_ref)] diff --git a/tests/ui/tabs_in_doc_comments.fixed b/tests/ui/tabs_in_doc_comments.fixed index 4bc4bc86c76c..21020182c241 100644 --- a/tests/ui/tabs_in_doc_comments.fixed +++ b/tests/ui/tabs_in_doc_comments.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::tabs_in_doc_comments)] #[allow(dead_code)] diff --git a/tests/ui/tabs_in_doc_comments.rs b/tests/ui/tabs_in_doc_comments.rs index 9db3416e6596..df704267dd25 100644 --- a/tests/ui/tabs_in_doc_comments.rs +++ b/tests/ui/tabs_in_doc_comments.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::tabs_in_doc_comments)] #[allow(dead_code)] diff --git a/tests/ui/tests_outside_test_module.rs b/tests/ui/tests_outside_test_module.rs index 1982b1d0107f..2a1d04779d80 100644 --- a/tests/ui/tests_outside_test_module.rs +++ b/tests/ui/tests_outside_test_module.rs @@ -1,4 +1,25 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@compile-flags: --test +======= // compile-flags: --test +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +//@compile-flags: --test +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +//@compile-flags: --test +>>>>>>> def1705a2 (Update to a compiletest-rs version that requires `//@` for commands) +======= +>>>>>>> 0d78a528d (Entered supposed changes, ran cargo dev fmt, test, and bless.) +======= +======= +//@compile-flags: --test +>>>>>>> e4f5d83fa (Fixed formatting.) +>>>>>>> 4da6e7e06 (rebase attempt) #![allow(unused)] #![warn(clippy::tests_outside_test_module)] diff --git a/tests/ui/tests_outside_test_module.stderr b/tests/ui/tests_outside_test_module.stderr index 125a79d6edfe..71c649c5d270 100644 --- a/tests/ui/tests_outside_test_module.stderr +++ b/tests/ui/tests_outside_test_module.stderr @@ -1,5 +1,5 @@ error: this function marked with #[test] is outside a #[cfg(test)] module - --> $DIR/tests_outside_test_module.rs:11:1 + --> $DIR/tests_outside_test_module.rs:10:1 | LL | fn my_test() {} | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/to_digit_is_some.fixed b/tests/ui/to_digit_is_some.fixed index 3c5e96427146..dc9be66d48ab 100644 --- a/tests/ui/to_digit_is_some.fixed +++ b/tests/ui/to_digit_is_some.fixed @@ -1,4 +1,4 @@ -//run-rustfix +//@run-rustfix #![warn(clippy::to_digit_is_some)] diff --git a/tests/ui/to_digit_is_some.rs b/tests/ui/to_digit_is_some.rs index 4f247c06ceed..d2a09ac30de4 100644 --- a/tests/ui/to_digit_is_some.rs +++ b/tests/ui/to_digit_is_some.rs @@ -1,4 +1,4 @@ -//run-rustfix +//@run-rustfix #![warn(clippy::to_digit_is_some)] diff --git a/tests/ui/to_digit_is_some.stderr b/tests/ui/to_digit_is_some.stderr index 10a1b393a390..c4718825dc26 100644 --- a/tests/ui/to_digit_is_some.stderr +++ b/tests/ui/to_digit_is_some.stderr @@ -2,7 +2,7 @@ error: use of `.to_digit(..).is_some()` --> $DIR/to_digit_is_some.rs:9:13 | LL | let _ = d.to_digit(8).is_some(); - | ^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `d.is_digit(8)` + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d.is_digit(8)` | = note: `-D clippy::to-digit-is-some` implied by `-D warnings` @@ -10,7 +10,7 @@ error: use of `.to_digit(..).is_some()` --> $DIR/to_digit_is_some.rs:10:13 | LL | let _ = char::to_digit(c, 8).is_some(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `char::is_digit(c, 8)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `char::is_digit(c, 8)` error: aborting due to 2 previous errors diff --git a/tests/ui/to_string_in_format_args_incremental.fixed b/tests/ui/to_string_in_format_args_incremental.fixed new file mode 100644 index 000000000000..9f75ad895cda --- /dev/null +++ b/tests/ui/to_string_in_format_args_incremental.fixed @@ -0,0 +1,9 @@ +//@run-rustfix +//@compile-flags: -C incremental=target/debug/test/incr + +// see https://github.com/rust-lang/rust-clippy/issues/10969 + +fn main() { + let s = "Hello, world!"; + println!("{}", s); +} diff --git a/tests/ui/to_string_in_format_args_incremental.rs b/tests/ui/to_string_in_format_args_incremental.rs new file mode 100644 index 000000000000..67115f7c5a7b --- /dev/null +++ b/tests/ui/to_string_in_format_args_incremental.rs @@ -0,0 +1,9 @@ +//@run-rustfix +//@compile-flags: -C incremental=target/debug/test/incr + +// see https://github.com/rust-lang/rust-clippy/issues/10969 + +fn main() { + let s = "Hello, world!"; + println!("{}", s.to_string()); +} diff --git a/tests/ui/to_string_in_format_args_incremental.stderr b/tests/ui/to_string_in_format_args_incremental.stderr new file mode 100644 index 000000000000..a992c5429149 --- /dev/null +++ b/tests/ui/to_string_in_format_args_incremental.stderr @@ -0,0 +1,10 @@ +error: `to_string` applied to a type that implements `Display` in `println!` args + --> $DIR/to_string_in_format_args_incremental.rs:8:21 + | +LL | println!("{}", s.to_string()); + | ^^^^^^^^^^^^ help: remove this + | + = note: `-D clippy::to-string-in-format-args` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/tests/ui/toplevel_ref_arg.fixed b/tests/ui/toplevel_ref_arg.fixed index 174c858a47d1..98b0ff88aabf 100644 --- a/tests/ui/toplevel_ref_arg.fixed +++ b/tests/ui/toplevel_ref_arg.fixed @@ -1,7 +1,11 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::toplevel_ref_arg)] -#![allow(clippy::uninlined_format_args, unused)] +#![allow(clippy::uninlined_format_args, unused, clippy::useless_vec)] extern crate proc_macros; use proc_macros::{external, inline_macros}; diff --git a/tests/ui/toplevel_ref_arg.rs b/tests/ui/toplevel_ref_arg.rs index 4b81a06112fe..674a68b19e17 100644 --- a/tests/ui/toplevel_ref_arg.rs +++ b/tests/ui/toplevel_ref_arg.rs @@ -1,7 +1,11 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::toplevel_ref_arg)] -#![allow(clippy::uninlined_format_args, unused)] +#![allow(clippy::uninlined_format_args, unused, clippy::useless_vec)] extern crate proc_macros; use proc_macros::{external, inline_macros}; diff --git a/tests/ui/toplevel_ref_arg_non_rustfix.rs b/tests/ui/toplevel_ref_arg_non_rustfix.rs index 2047593e7e4b..8022003380a2 100644 --- a/tests/ui/toplevel_ref_arg_non_rustfix.rs +++ b/tests/ui/toplevel_ref_arg_non_rustfix.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::toplevel_ref_arg)] #![allow(unused)] diff --git a/tests/ui/track-diagnostics.rs b/tests/ui/track-diagnostics.rs index fa9221ed02d7..6ab0bce770e2 100644 --- a/tests/ui/track-diagnostics.rs +++ b/tests/ui/track-diagnostics.rs @@ -1,9 +1,8 @@ -// compile-flags: -Z track-diagnostics -// error-pattern: created at +//@compile-flags: -Z track-diagnostics // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" +//@normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" struct A; struct B; diff --git a/tests/ui/trailing_empty_array.rs b/tests/ui/trailing_empty_array.rs index 8e3749eef351..928475b5f35e 100644 --- a/tests/ui/trailing_empty_array.rs +++ b/tests/ui/trailing_empty_array.rs @@ -144,7 +144,7 @@ struct ReprCAlign { // NOTE: because of https://doc.rust-lang.org/stable/reference/type-layout.html#primitive-representation-of-enums-with-fields and I'm not sure when in the compilation pipeline that would happen #[repr(C)] -enum DontLintAnonymousStructsFromDesuraging { +enum DontLintAnonymousStructsFromDesugaring { A(u32), B(f32, [u64; 0]), C { x: u32, y: [u64; 0] }, diff --git a/tests/ui/trait_duplication_in_bounds.fixed b/tests/ui/trait_duplication_in_bounds.fixed index 4ce5d4217822..fdac0e4cb1e8 100644 --- a/tests/ui/trait_duplication_in_bounds.fixed +++ b/tests/ui/trait_duplication_in_bounds.fixed @@ -1,7 +1,9 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] +use std::any::Any; + fn bad_foo(arg0: T, argo1: U) { unimplemented!(); } @@ -109,4 +111,12 @@ fn qualified_path(arg0: T) { unimplemented!(); } +fn good_trait_object(arg0: &(dyn Any + Send)) { + unimplemented!(); +} + +fn bad_trait_object(arg0: &(dyn Any + Send)) { + unimplemented!(); +} + fn main() {} diff --git a/tests/ui/trait_duplication_in_bounds.rs b/tests/ui/trait_duplication_in_bounds.rs index 7f2e96a22e66..a0300da55558 100644 --- a/tests/ui/trait_duplication_in_bounds.rs +++ b/tests/ui/trait_duplication_in_bounds.rs @@ -1,7 +1,9 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] +use std::any::Any; + fn bad_foo(arg0: T, argo1: U) { unimplemented!(); } @@ -109,4 +111,12 @@ fn qualified_path(arg0: T) { unimplemented!(); } +fn good_trait_object(arg0: &(dyn Any + Send)) { + unimplemented!(); +} + +fn bad_trait_object(arg0: &(dyn Any + Send + Send)) { + unimplemented!(); +} + fn main() {} diff --git a/tests/ui/trait_duplication_in_bounds.stderr b/tests/ui/trait_duplication_in_bounds.stderr index af800ba78880..91e6ab0cdfe1 100644 --- a/tests/ui/trait_duplication_in_bounds.stderr +++ b/tests/ui/trait_duplication_in_bounds.stderr @@ -1,5 +1,5 @@ error: these bounds contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:5:15 + --> $DIR/trait_duplication_in_bounds.rs:7:15 | LL | fn bad_foo(arg0: T, argo1: U) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` @@ -11,46 +11,67 @@ LL | #![deny(clippy::trait_duplication_in_bounds)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: these where clauses contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:11:8 + --> $DIR/trait_duplication_in_bounds.rs:13:8 | LL | T: Clone + Clone + Clone + Copy, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` error: these bounds contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:39:26 + --> $DIR/trait_duplication_in_bounds.rs:41:26 | LL | trait BadSelfTraitBound: Clone + Clone + Clone { | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone` error: these where clauses contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:46:15 + --> $DIR/trait_duplication_in_bounds.rs:48:15 | LL | Self: Clone + Clone + Clone; | ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone` error: these bounds contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:60:24 + --> $DIR/trait_duplication_in_bounds.rs:62:24 | LL | trait BadTraitBound { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` error: these where clauses contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:67:12 + --> $DIR/trait_duplication_in_bounds.rs:69:12 | LL | T: Clone + Clone + Clone + Copy, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy` error: these bounds contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:100:19 + --> $DIR/trait_duplication_in_bounds.rs:102:19 | LL | fn bad_generic + GenericTrait + GenericTrait>(arg0: T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `GenericTrait + GenericTrait` error: these bounds contain repeated elements - --> $DIR/trait_duplication_in_bounds.rs:108:22 + --> $DIR/trait_duplication_in_bounds.rs:110:22 | LL | fn qualified_path(arg0: T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::clone::Clone + foo::Clone` -error: aborting due to 8 previous errors +error: this trait bound is already specified in trait declaration +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/trait_duplication_in_bounds.rs:118:33 + | +LL | fn bad_trait_object(arg0: &(dyn Any + Send + Send)) { + | ^^^^^^^^^^^^^^^^^ help: try: `Any + Send` +======= + --> $DIR/trait_duplication_in_bounds.rs:118:46 + | +LL | fn bad_trait_object(arg0: &(dyn Any + Send + Send)) { + | ^^^^ help: consider removing this trait bound + | +>>>>>>> 1eff408ca (WIP) +======= + --> $DIR/trait_duplication_in_bounds.rs:118:33 + | +LL | fn bad_trait_object(arg0: &(dyn Any + Send + Send)) { + | ^^^^^^^^^^^^^^^^^ help: try: `Any + Send` +>>>>>>> b9788fef2 (Working) + +error: aborting due to 9 previous errors diff --git a/tests/ui/transmute_32bit.rs b/tests/ui/transmute_32bit.rs index ffe22b12f551..8e1316ca39d4 100644 --- a/tests/ui/transmute_32bit.rs +++ b/tests/ui/transmute_32bit.rs @@ -1,4 +1,4 @@ -// ignore-64bit +//@ignore-64bit #[warn(clippy::wrong_transmute)] fn main() { diff --git a/tests/ui/transmute_32bit.stderr b/tests/ui/transmute_32bit.stderr index 040519564b94..75ddca60d2aa 100644 --- a/tests/ui/transmute_32bit.stderr +++ b/tests/ui/transmute_32bit.stderr @@ -1,28 +1,39 @@ -error: transmute from a `f32` to a pointer +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types --> $DIR/transmute_32bit.rs:6:31 | LL | let _: *const usize = std::mem::transmute(6.0f32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::wrong-transmute` implied by `-D warnings` + = note: source type: `f32` (32 bits) + = note: target type: `*const usize` (64 bits) -error: transmute from a `f32` to a pointer +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types --> $DIR/transmute_32bit.rs:8:29 | LL | let _: *mut usize = std::mem::transmute(6.0f32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `f32` (32 bits) + = note: target type: `*mut usize` (64 bits) -error: transmute from a `char` to a pointer +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types --> $DIR/transmute_32bit.rs:10:31 | LL | let _: *const usize = std::mem::transmute('x'); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `char` (32 bits) + = note: target type: `*const usize` (64 bits) -error: transmute from a `char` to a pointer +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types --> $DIR/transmute_32bit.rs:12:29 | LL | let _: *mut usize = std::mem::transmute('x'); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `char` (32 bits) + = note: target type: `*mut usize` (64 bits) error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/transmute_64bit.rs b/tests/ui/transmute_64bit.rs index 00dc0b2c3608..ceecf9b279f0 100644 --- a/tests/ui/transmute_64bit.rs +++ b/tests/ui/transmute_64bit.rs @@ -1,4 +1,4 @@ -// ignore-32bit +//@ignore-32bit #[warn(clippy::wrong_transmute)] fn main() { diff --git a/tests/ui/transmute_ptr_to_ptr.rs b/tests/ui/transmute_ptr_to_ptr.rs index f06ffab5d9be..61a6c98ed5ac 100644 --- a/tests/ui/transmute_ptr_to_ptr.rs +++ b/tests/ui/transmute_ptr_to_ptr.rs @@ -32,7 +32,7 @@ fn transmute_ptr_to_ptr() { // ref-ref transmutes; bad let _: &f32 = std::mem::transmute(&1u32); let _: &f64 = std::mem::transmute(&1f32); - // ^ this test is here because both f32 and f64 are the same TypeVariant, but they are not + //:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not // the same type let _: &mut f32 = std::mem::transmute(&mut 1u32); let _: &GenericParam = std::mem::transmute(&GenericParam { t: 1u32 }); diff --git a/tests/ui/transmute_ptr_to_ref.fixed b/tests/ui/transmute_ptr_to_ref.fixed index 074dae5fb286..215f0ac18422 100644 --- a/tests/ui/transmute_ptr_to_ref.fixed +++ b/tests/ui/transmute_ptr_to_ref.fixed @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::transmute_ptr_to_ref)] -#![allow(clippy::match_single_binding)] +#![allow(clippy::match_single_binding, clippy::unnecessary_cast)] unsafe fn _ptr_to_ref(p: *const T, m: *mut T, o: *const U, om: *mut U) { let _: &T = &*p; diff --git a/tests/ui/transmute_ptr_to_ref.rs b/tests/ui/transmute_ptr_to_ref.rs index 2edc122cf471..3528e1379039 100644 --- a/tests/ui/transmute_ptr_to_ref.rs +++ b/tests/ui/transmute_ptr_to_ref.rs @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::transmute_ptr_to_ref)] -#![allow(clippy::match_single_binding)] +#![allow(clippy::match_single_binding, clippy::unnecessary_cast)] unsafe fn _ptr_to_ref(p: *const T, m: *mut T, o: *const U, om: *mut U) { let _: &T = std::mem::transmute(p); diff --git a/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/tests/ui/transmutes_expressible_as_ptr_casts.fixed index cc84ba25bd0d..05aa86c479ad 100644 --- a/tests/ui/transmutes_expressible_as_ptr_casts.fixed +++ b/tests/ui/transmutes_expressible_as_ptr_casts.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::transmutes_expressible_as_ptr_casts)] // These two warnings currently cover the cases transmutes_expressible_as_ptr_casts // would otherwise be responsible for diff --git a/tests/ui/transmutes_expressible_as_ptr_casts.rs b/tests/ui/transmutes_expressible_as_ptr_casts.rs index aa65ab4dd247..29fa6914cfd0 100644 --- a/tests/ui/transmutes_expressible_as_ptr_casts.rs +++ b/tests/ui/transmutes_expressible_as_ptr_casts.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::transmutes_expressible_as_ptr_casts)] // These two warnings currently cover the cases transmutes_expressible_as_ptr_casts // would otherwise be responsible for diff --git a/tests/ui/trim_split_whitespace.fixed b/tests/ui/trim_split_whitespace.fixed index e4d352f7367e..7909b319ddd5 100644 --- a/tests/ui/trim_split_whitespace.fixed +++ b/tests/ui/trim_split_whitespace.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::trim_split_whitespace)] #![allow(clippy::let_unit_value)] diff --git a/tests/ui/trim_split_whitespace.rs b/tests/ui/trim_split_whitespace.rs index f98451a98371..0cf58979fb20 100644 --- a/tests/ui/trim_split_whitespace.rs +++ b/tests/ui/trim_split_whitespace.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::trim_split_whitespace)] #![allow(clippy::let_unit_value)] diff --git a/tests/ui/trivially_copy_pass_by_ref.rs b/tests/ui/trivially_copy_pass_by_ref.rs index c0af011d33d0..86f5cc937f44 100644 --- a/tests/ui/trivially_copy_pass_by_ref.rs +++ b/tests/ui/trivially_copy_pass_by_ref.rs @@ -1,11 +1,12 @@ -// normalize-stderr-test "\(\d+ byte\)" -> "(N byte)" -// normalize-stderr-test "\(limit: \d+ byte\)" -> "(limit: N byte)" +//@normalize-stderr-test: "\(\d+ byte\)" -> "(N byte)" +//@normalize-stderr-test: "\(limit: \d+ byte\)" -> "(limit: N byte)" #![deny(clippy::trivially_copy_pass_by_ref)] #![allow( clippy::disallowed_names, clippy::needless_lifetimes, clippy::redundant_field_names, - clippy::uninlined_format_args + clippy::uninlined_format_args, + clippy::needless_pass_by_ref_mut )] #[derive(Copy, Clone)] diff --git a/tests/ui/trivially_copy_pass_by_ref.stderr b/tests/ui/trivially_copy_pass_by_ref.stderr index 8c5cfa8a0f17..2af668537f5c 100644 --- a/tests/ui/trivially_copy_pass_by_ref.stderr +++ b/tests/ui/trivially_copy_pass_by_ref.stderr @@ -1,5 +1,5 @@ error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:51:11 + --> $DIR/trivially_copy_pass_by_ref.rs:52:11 | LL | fn bad(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `u32` @@ -11,103 +11,103 @@ LL | #![deny(clippy::trivially_copy_pass_by_ref)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:51:20 + --> $DIR/trivially_copy_pass_by_ref.rs:52:20 | LL | fn bad(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:51:29 + --> $DIR/trivially_copy_pass_by_ref.rs:52:29 | LL | fn bad(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:58:12 + --> $DIR/trivially_copy_pass_by_ref.rs:59:12 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^^ help: consider passing by value instead: `self` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:58:22 + --> $DIR/trivially_copy_pass_by_ref.rs:59:22 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `u32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:58:31 + --> $DIR/trivially_copy_pass_by_ref.rs:59:31 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:58:40 + --> $DIR/trivially_copy_pass_by_ref.rs:59:40 | LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:60:16 + --> $DIR/trivially_copy_pass_by_ref.rs:61:16 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `u32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:60:25 + --> $DIR/trivially_copy_pass_by_ref.rs:61:25 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:60:34 + --> $DIR/trivially_copy_pass_by_ref.rs:61:34 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:62:35 + --> $DIR/trivially_copy_pass_by_ref.rs:63:35 | LL | fn bad_issue7518(self, other: &Self) {} | ^^^^^ help: consider passing by value instead: `Self` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:74:16 + --> $DIR/trivially_copy_pass_by_ref.rs:75:16 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `u32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:74:25 + --> $DIR/trivially_copy_pass_by_ref.rs:75:25 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:74:34 + --> $DIR/trivially_copy_pass_by_ref.rs:75:34 | LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {} | ^^^^ help: consider passing by value instead: `Baz` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:78:34 + --> $DIR/trivially_copy_pass_by_ref.rs:79:34 | LL | fn trait_method(&self, _foo: &Foo); | ^^^^ help: consider passing by value instead: `Foo` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:110:21 + --> $DIR/trivially_copy_pass_by_ref.rs:111:21 | LL | fn foo_never(x: &i32) { | ^^^^ help: consider passing by value instead: `i32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:115:15 + --> $DIR/trivially_copy_pass_by_ref.rs:116:15 | LL | fn foo(x: &i32) { | ^^^^ help: consider passing by value instead: `i32` error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte) - --> $DIR/trivially_copy_pass_by_ref.rs:142:37 + --> $DIR/trivially_copy_pass_by_ref.rs:143:37 | LL | fn _unrelated_lifetimes<'a, 'b>(_x: &'a u32, y: &'b u32) -> &'b u32 { | ^^^^^^^ help: consider passing by value instead: `u32` diff --git a/tests/ui/try_err.fixed b/tests/ui/try_err.fixed index dc497b1690f5..b176d3e7cbfe 100644 --- a/tests/ui/try_err.fixed +++ b/tests/ui/try_err.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![deny(clippy::try_err)] #![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] diff --git a/tests/ui/try_err.rs b/tests/ui/try_err.rs index 86aeb75cd96a..e7be60c32cad 100644 --- a/tests/ui/try_err.rs +++ b/tests/ui/try_err.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![deny(clippy::try_err)] #![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] diff --git a/tests/ui/try_err.stderr b/tests/ui/try_err.stderr index 4ad0e2e56a4d..79f7b70224a1 100644 --- a/tests/ui/try_err.stderr +++ b/tests/ui/try_err.stderr @@ -2,7 +2,7 @@ error: returning an `Err(_)` with the `?` operator --> $DIR/try_err.rs:19:9 | LL | Err(err)?; - | ^^^^^^^^^ help: try this: `return Err(err)` + | ^^^^^^^^^ help: try: `return Err(err)` | note: the lint level is defined here --> $DIR/try_err.rs:4:9 @@ -14,25 +14,25 @@ error: returning an `Err(_)` with the `?` operator --> $DIR/try_err.rs:29:9 | LL | Err(err)?; - | ^^^^^^^^^ help: try this: `return Err(err.into())` + | ^^^^^^^^^ help: try: `return Err(err.into())` error: returning an `Err(_)` with the `?` operator --> $DIR/try_err.rs:49:17 | LL | Err(err)?; - | ^^^^^^^^^ help: try this: `return Err(err)` + | ^^^^^^^^^ help: try: `return Err(err)` error: returning an `Err(_)` with the `?` operator --> $DIR/try_err.rs:68:17 | LL | Err(err)?; - | ^^^^^^^^^ help: try this: `return Err(err.into())` + | ^^^^^^^^^ help: try: `return Err(err.into())` error: returning an `Err(_)` with the `?` operator --> $DIR/try_err.rs:88:23 | LL | Err(_) => Err(1)?, - | ^^^^^^^ help: try this: `return Err(1)` + | ^^^^^^^ help: try: `return Err(1)` | = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -40,7 +40,7 @@ error: returning an `Err(_)` with the `?` operator --> $DIR/try_err.rs:95:23 | LL | Err(_) => Err(inline!(1))?, - | ^^^^^^^^^^^^^^^^ help: try this: `return Err(inline!(1))` + | ^^^^^^^^^^^^^^^^ help: try: `return Err(inline!(1))` | = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -48,31 +48,31 @@ error: returning an `Err(_)` with the `?` operator --> $DIR/try_err.rs:122:9 | LL | Err(inline!(inline!(String::from("aasdfasdfasdfa"))))?; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Err(inline!(inline!(String::from("aasdfasdfasdfa"))))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Err(inline!(inline!(String::from("aasdfasdfasdfa"))))` error: returning an `Err(_)` with the `?` operator --> $DIR/try_err.rs:129:9 | LL | Err(io::ErrorKind::WriteZero)? - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))` error: returning an `Err(_)` with the `?` operator --> $DIR/try_err.rs:131:9 | LL | Err(io::Error::new(io::ErrorKind::InvalidInput, "error"))? - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, "error")))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, "error")))` error: returning an `Err(_)` with the `?` operator --> $DIR/try_err.rs:139:9 | LL | Err(io::ErrorKind::NotFound)? - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into())))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into())))` error: returning an `Err(_)` with the `?` operator --> $DIR/try_err.rs:148:16 | LL | return Err(42)?; - | ^^^^^^^^ help: try this: `Err(42)` + | ^^^^^^^^ help: try: `Err(42)` error: aborting due to 11 previous errors diff --git a/tests/ui/tuple_array_conversions.rs b/tests/ui/tuple_array_conversions.rs new file mode 100644 index 000000000000..6b832ee27e9b --- /dev/null +++ b/tests/ui/tuple_array_conversions.rs @@ -0,0 +1,118 @@ +//@aux-build:proc_macros.rs:proc-macro +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::no_effect, clippy::useless_vec, unused)] +======= +#![allow(clippy::useless_vec, unused)] +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= +#![allow(clippy::no_effect, clippy::useless_vec, unused)] +>>>>>>> b1acbde61 (Add msrv check and make test pass) +#![warn(clippy::tuple_array_conversions)] + +#[macro_use] +extern crate proc_macros; + +fn main() { + let x = [1, 2]; + let x = (x[0], x[1]); + let x = [x.0, x.1]; + let x = &[1, 2]; + let x = (x[0], x[1]); + + let t1: &[(u32, u32)] = &[(1, 2), (3, 4)]; + let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect(); + t1.iter().for_each(|&(a, b)| _ = [a, b]); + let t2: Vec<(u32, u32)> = v1.iter().map(|&[a, b]| (a, b)).collect(); + t1.iter().for_each(|&(a, b)| _ = [a, b]); + // Do not lint + let v2: Vec<[u32; 2]> = t1.iter().map(|&t| t.into()).collect(); + let t3: Vec<(u32, u32)> = v2.iter().map(|&v| v.into()).collect(); + let x = [1; 13]; +<<<<<<< HEAD +<<<<<<< HEAD + let x = ( + x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], + ); +======= + let x = (x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12]); +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + let x = ( + x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], + ); +>>>>>>> b1acbde61 (Add msrv check and make test pass) + let x = [x.0, x.1, x.2, x.3, x.4, x.5, x.6, x.7, x.8, x.9, x.10, x.11, x.12]; + let x = (1, 2); + let x = (x.0, x.1); + let x = [1, 2]; + let x = [x[0], x[1]]; + let x = vec![1, 2]; + let x = (x[0], x[1]); +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> b1acbde61 (Add msrv check and make test pass) + let x = [1; 3]; + let x = (x[0],); + let x = (1, 2, 3); + let x = [x.0]; + let x = (1, 2); + let y = (1, 2); + [x.0, y.0]; + [x.0, y.1]; +<<<<<<< HEAD +<<<<<<< HEAD + let x = [x.0, x.0]; + let x = (x[0], x[0]); +======= +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + // FP + let x = [x.0, x.0]; + let x = (x[0], x[0]); + // How can this be fixed? +>>>>>>> b1acbde61 (Add msrv check and make test pass) +======= + let x = [x.0, x.0]; + let x = (x[0], x[0]); +>>>>>>> 95b24d44a (Fix FP) + external! { + let t1: &[(u32, u32)] = &[(1, 2), (3, 4)]; + let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect(); + let t2: Vec<(u32, u32)> = v1.iter().map(|&[a, b]| (a, b)).collect(); + } + with_span! { + span + let t1: &[(u32, u32)] = &[(1, 2), (3, 4)]; + let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect(); + let t2: Vec<(u32, u32)> = v1.iter().map(|&[a, b]| (a, b)).collect(); + } +} +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> b1acbde61 (Add msrv check and make test pass) + +#[clippy::msrv = "1.70.0"] +fn msrv_too_low() { + let x = [1, 2]; + let x = (x[0], x[1]); + let x = [x.0, x.1]; + let x = &[1, 2]; + let x = (x[0], x[1]); +} + +#[clippy::msrv = "1.71.0"] +fn msrv_juust_right() { + let x = [1, 2]; + let x = (x[0], x[1]); + let x = [x.0, x.1]; + let x = &[1, 2]; + let x = (x[0], x[1]); +} +<<<<<<< HEAD +======= +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= +>>>>>>> b1acbde61 (Add msrv check and make test pass) diff --git a/tests/ui/tuple_array_conversions.stderr b/tests/ui/tuple_array_conversions.stderr new file mode 100644 index 000000000000..02e7471637ee --- /dev/null +++ b/tests/ui/tuple_array_conversions.stderr @@ -0,0 +1,171 @@ +error: it looks like you're trying to convert an array to a tuple + --> $DIR/tuple_array_conversions.rs:10:13 + | +LL | let x = (x[0], x[1]); + | ^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed +======= + = help: use `.into()` instead +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed +>>>>>>> b1acbde61 (Add msrv check and make test pass) + = note: `-D clippy::tuple-array-conversions` implied by `-D warnings` + +error: it looks like you're trying to convert a tuple to an array + --> $DIR/tuple_array_conversions.rs:11:13 + | +LL | let x = [x.0, x.1]; + | ^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD + = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed +======= + = help: use `.into()` instead +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed +>>>>>>> b1acbde61 (Add msrv check and make test pass) + +error: it looks like you're trying to convert an array to a tuple + --> $DIR/tuple_array_conversions.rs:13:13 + | +LL | let x = (x[0], x[1]); + | ^^^^^^^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed +======= + = help: use `.into()` instead +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed +>>>>>>> b1acbde61 (Add msrv check and make test pass) + +error: it looks like you're trying to convert a tuple to an array + --> $DIR/tuple_array_conversions.rs:16:53 + | +LL | let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect(); + | ^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD + = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed +======= + = help: use `.into()` instead +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed +>>>>>>> b1acbde61 (Add msrv check and make test pass) + +error: it looks like you're trying to convert a tuple to an array + --> $DIR/tuple_array_conversions.rs:17:38 + | +LL | t1.iter().for_each(|&(a, b)| _ = [a, b]); + | ^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD + = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed +======= + = help: use `.into()` instead +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed +>>>>>>> b1acbde61 (Add msrv check and make test pass) + +error: it looks like you're trying to convert an array to a tuple + --> $DIR/tuple_array_conversions.rs:18:55 + | +LL | let t2: Vec<(u32, u32)> = v1.iter().map(|&[a, b]| (a, b)).collect(); + | ^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed +======= + = help: use `.into()` instead +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed +>>>>>>> b1acbde61 (Add msrv check and make test pass) + +error: it looks like you're trying to convert a tuple to an array + --> $DIR/tuple_array_conversions.rs:19:38 + | +LL | t1.iter().for_each(|&(a, b)| _ = [a, b]); + | ^^^^^^ + | +<<<<<<< HEAD +<<<<<<< HEAD + = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed + +error: it looks like you're trying to convert an array to a tuple + --> $DIR/tuple_array_conversions.rs:69:13 + | +LL | let x = (x[0], x[1]); + | ^^^^^^^^^^^^ + | + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed + +error: it looks like you're trying to convert a tuple to an array + --> $DIR/tuple_array_conversions.rs:70:13 + | +LL | let x = [x.0, x.1]; + | ^^^^^^^^^^ + | + = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed + +error: it looks like you're trying to convert an array to a tuple + --> $DIR/tuple_array_conversions.rs:72:13 + | +LL | let x = (x[0], x[1]); + | ^^^^^^^^^^^^ + | + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed + +error: aborting due to 10 previous errors +======= + = help: use `.into()` instead + +error: aborting due to 7 previous errors +>>>>>>> bfcc8ba44 (New lint `tuple_array_conversions`) +======= + = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed + +error: it looks like you're trying to convert an array to a tuple + --> $DIR/tuple_array_conversions.rs:69:13 + | +LL | let x = (x[0], x[1]); + | ^^^^^^^^^^^^ + | + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed + +error: it looks like you're trying to convert a tuple to an array + --> $DIR/tuple_array_conversions.rs:70:13 + | +LL | let x = [x.0, x.1]; + | ^^^^^^^^^^ + | + = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed + +error: it looks like you're trying to convert an array to a tuple + --> $DIR/tuple_array_conversions.rs:72:13 + | +LL | let x = (x[0], x[1]); + | ^^^^^^^^^^^^ + | + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed + +<<<<<<< HEAD +error: aborting due to 12 previous errors +>>>>>>> b1acbde61 (Add msrv check and make test pass) +======= +error: aborting due to 10 previous errors +>>>>>>> 95b24d44a (Fix FP) + diff --git a/tests/ui/type_complexity.rs b/tests/ui/type_complexity.rs index 86a7bd7b6273..816950110b20 100644 --- a/tests/ui/type_complexity.rs +++ b/tests/ui/type_complexity.rs @@ -1,5 +1,5 @@ #![warn(clippy::all)] -#![allow(unused, clippy::needless_pass_by_value, clippy::vec_box)] +#![allow(unused, clippy::needless_pass_by_value, clippy::vec_box, clippy::useless_vec)] #![feature(associated_type_defaults)] type Alias = Vec>>; // no warning here diff --git a/tests/ui/type_id_on_box.fixed b/tests/ui/type_id_on_box.fixed new file mode 100644 index 000000000000..615d809c8975 --- /dev/null +++ b/tests/ui/type_id_on_box.fixed @@ -0,0 +1,40 @@ +//@run-rustfix + +#![warn(clippy::type_id_on_box)] + +use std::any::{Any, TypeId}; +use std::ops::Deref; + +type SomeBox = Box; + +struct BadBox(Box); + +impl Deref for BadBox { + type Target = Box; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +fn existential() -> impl Any { + Box::new(1) as Box +} + +fn main() { + let any_box: Box = Box::new(0usize); + let _ = (*any_box).type_id(); + let _ = TypeId::of::>(); // Don't lint. We explicitly say "do this instead" if this is intentional + let _ = (*any_box).type_id(); + let any_box: &Box = &(Box::new(0usize) as Box); + let _ = (**any_box).type_id(); // 2 derefs are needed here to get to the `dyn Any` + + let b = existential(); + let _ = b.type_id(); // Don't lint. + + let b: SomeBox = Box::new(0usize); + let _ = (*b).type_id(); + + let b = BadBox(Box::new(0usize)); + let _ = b.type_id(); // Don't lint. This is a call to `::type_id`. Not `std::boxed::Box`! +} diff --git a/tests/ui/type_id_on_box.rs b/tests/ui/type_id_on_box.rs new file mode 100644 index 000000000000..74b6c74ae5f6 --- /dev/null +++ b/tests/ui/type_id_on_box.rs @@ -0,0 +1,40 @@ +//@run-rustfix + +#![warn(clippy::type_id_on_box)] + +use std::any::{Any, TypeId}; +use std::ops::Deref; + +type SomeBox = Box; + +struct BadBox(Box); + +impl Deref for BadBox { + type Target = Box; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +fn existential() -> impl Any { + Box::new(1) as Box +} + +fn main() { + let any_box: Box = Box::new(0usize); + let _ = any_box.type_id(); + let _ = TypeId::of::>(); // Don't lint. We explicitly say "do this instead" if this is intentional + let _ = (*any_box).type_id(); + let any_box: &Box = &(Box::new(0usize) as Box); + let _ = any_box.type_id(); // 2 derefs are needed here to get to the `dyn Any` + + let b = existential(); + let _ = b.type_id(); // Don't lint. + + let b: SomeBox = Box::new(0usize); + let _ = b.type_id(); + + let b = BadBox(Box::new(0usize)); + let _ = b.type_id(); // Don't lint. This is a call to `::type_id`. Not `std::boxed::Box`! +} diff --git a/tests/ui/type_id_on_box.stderr b/tests/ui/type_id_on_box.stderr new file mode 100644 index 000000000000..1525328c0d03 --- /dev/null +++ b/tests/ui/type_id_on_box.stderr @@ -0,0 +1,36 @@ +error: calling `.type_id()` on a `Box` + --> $DIR/type_id_on_box.rs:26:13 + | +LL | let _ = any_box.type_id(); + | -------^^^^^^^^^^ + | | + | help: consider dereferencing first: `(*any_box)` + | + = note: this returns the type id of the literal type `Box` instead of the type id of the boxed value, which is most likely not what you want + = note: if this is intentional, use `TypeId::of::>()` instead, which makes it more clear + = note: `-D clippy::type-id-on-box` implied by `-D warnings` + +error: calling `.type_id()` on a `Box` + --> $DIR/type_id_on_box.rs:30:13 + | +LL | let _ = any_box.type_id(); // 2 derefs are needed here to get to the `dyn Any` + | -------^^^^^^^^^^ + | | + | help: consider dereferencing first: `(**any_box)` + | + = note: this returns the type id of the literal type `Box` instead of the type id of the boxed value, which is most likely not what you want + = note: if this is intentional, use `TypeId::of::>()` instead, which makes it more clear + +error: calling `.type_id()` on a `Box` + --> $DIR/type_id_on_box.rs:36:13 + | +LL | let _ = b.type_id(); + | -^^^^^^^^^^ + | | + | help: consider dereferencing first: `(*b)` + | + = note: this returns the type id of the literal type `Box` instead of the type id of the boxed value, which is most likely not what you want + = note: if this is intentional, use `TypeId::of::>()` instead, which makes it more clear + +error: aborting due to 3 previous errors + diff --git a/tests/ui/type_repetition_in_bounds.rs b/tests/ui/type_repetition_in_bounds.rs index 8b4613b3f6ec..874d97f7a46c 100644 --- a/tests/ui/type_repetition_in_bounds.rs +++ b/tests/ui/type_repetition_in_bounds.rs @@ -1,6 +1,7 @@ #![deny(clippy::type_repetition_in_bounds)] #![allow(clippy::extra_unused_type_parameters)] +use serde::Deserialize; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; pub fn foo(_t: T) @@ -70,6 +71,20 @@ mod issue4326 { } } +// Extern macros shouldn't lint, again (see #10504) +mod issue10504 { + use serde::{Deserialize, Serialize}; + use std::fmt::Debug; + use std::hash::Hash; + + #[derive(Debug, Serialize, Deserialize)] + #[serde(bound( + serialize = "T: Serialize + Hash + Eq", + deserialize = "Box: serde::de::DeserializeOwned + Hash + Eq" + ))] + struct OpaqueParams(std::marker::PhantomData); +} + // Issue #7360 struct Foo where @@ -95,4 +110,28 @@ where // This should not lint fn impl_trait(_: impl AsRef, _: impl AsRef) {} +#[clippy::msrv = "1.14.0"] +mod issue8772_fail { + pub trait Trait {} + + pub fn f(arg: usize) + where + T: Trait, Box<[String]>, bool> + 'static, + U: Clone + Sync + 'static, + { + } +} + +#[clippy::msrv = "1.15.0"] +mod issue8772_pass { + pub trait Trait {} + + pub fn f(arg: usize) + where + T: Trait, Box<[String]>, bool> + 'static, + U: Clone + Sync + 'static, + { + } +} + fn main() {} diff --git a/tests/ui/type_repetition_in_bounds.stderr b/tests/ui/type_repetition_in_bounds.stderr index a90df03c04ff..54973c5bda57 100644 --- a/tests/ui/type_repetition_in_bounds.stderr +++ b/tests/ui/type_repetition_in_bounds.stderr @@ -1,5 +1,5 @@ error: this type has already been used as a bound predicate - --> $DIR/type_repetition_in_bounds.rs:9:5 + --> $DIR/type_repetition_in_bounds.rs:10:5 | LL | T: Clone, | ^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(clippy::type_repetition_in_bounds)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this type has already been used as a bound predicate - --> $DIR/type_repetition_in_bounds.rs:26:5 + --> $DIR/type_repetition_in_bounds.rs:27:5 | LL | Self: Copy + Default + Ord, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | Self: Copy + Default + Ord, = help: consider combining the bounds: `Self: Clone + Copy + Default + Ord` error: this type has already been used as a bound predicate - --> $DIR/type_repetition_in_bounds.rs:86:5 + --> $DIR/type_repetition_in_bounds.rs:101:5 | LL | T: Clone, | ^^^^^^^^ @@ -28,12 +28,20 @@ LL | T: Clone, = help: consider combining the bounds: `T: ?Sized + Clone` error: this type has already been used as a bound predicate - --> $DIR/type_repetition_in_bounds.rs:91:5 + --> $DIR/type_repetition_in_bounds.rs:106:5 | LL | T: ?Sized, | ^^^^^^^^^ | = help: consider combining the bounds: `T: Clone + ?Sized` -error: aborting due to 4 previous errors +error: this type has already been used as a bound predicate + --> $DIR/type_repetition_in_bounds.rs:131:9 + | +LL | T: Trait, Box<[String]>, bool> + 'static, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider combining the bounds: `T: ?Sized + Trait, Box<[String]>, bool>` + +error: aborting due to 5 previous errors diff --git a/tests/ui/types.fixed b/tests/ui/types.fixed index 417da42edf17..4a2616a7a228 100644 --- a/tests/ui/types.fixed +++ b/tests/ui/types.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_variables)] #![warn(clippy::cast_lossless)] diff --git a/tests/ui/types.rs b/tests/ui/types.rs index b16e9e538b10..5e0917907db7 100644 --- a/tests/ui/types.rs +++ b/tests/ui/types.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_variables)] #![warn(clippy::cast_lossless)] diff --git a/tests/ui/unchecked_duration_subtraction.fixed b/tests/ui/unchecked_duration_subtraction.fixed index a0e49a8beb1e..757d15921847 100644 --- a/tests/ui/unchecked_duration_subtraction.fixed +++ b/tests/ui/unchecked_duration_subtraction.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unchecked_duration_subtraction)] use std::time::{Duration, Instant}; diff --git a/tests/ui/unchecked_duration_subtraction.rs b/tests/ui/unchecked_duration_subtraction.rs index a14a7ea57cc5..da7faab6753e 100644 --- a/tests/ui/unchecked_duration_subtraction.rs +++ b/tests/ui/unchecked_duration_subtraction.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unchecked_duration_subtraction)] use std::time::{Duration, Instant}; diff --git a/tests/ui/undocumented_unsafe_blocks.rs b/tests/ui/undocumented_unsafe_blocks.rs index c05eb447b2eb..546d26ecf928 100644 --- a/tests/ui/undocumented_unsafe_blocks.rs +++ b/tests/ui/undocumented_unsafe_blocks.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macro_unsafe.rs +<<<<<<< HEAD +//@aux-build:proc_macro_unsafe.rs:proc-macro +======= +//@aux-build:proc_macro_unsafe.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)] #![allow(clippy::let_unit_value, clippy::missing_safety_doc)] @@ -509,4 +513,44 @@ fn issue_9142() { }; } +pub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 { + 1 +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> e2e6a0244 (Addressing reviewer comments) +pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -> u32 { + 2 +} + +<<<<<<< HEAD +======= +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= +>>>>>>> e2e6a0244 (Addressing reviewer comments) +fn issue_10832() { + // Safety: A safety comment. But it will warn anyways + let _some_variable_with_a_very_long_name_to_break_the_line = + unsafe { a_function_with_a_very_long_name_to_break_the_line() }; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> e2e6a0244 (Addressing reviewer comments) + + // Safety: Another safety comment. But it will warn anyways + const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + + // Safety: Yet another safety comment. But it will warn anyways + static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; +<<<<<<< HEAD +======= +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= +>>>>>>> e2e6a0244 (Addressing reviewer comments) +} + fn main() {} diff --git a/tests/ui/undocumented_unsafe_blocks.stderr b/tests/ui/undocumented_unsafe_blocks.stderr index d1c1bb5ffeac..b8ec0f9094af 100644 --- a/tests/ui/undocumented_unsafe_blocks.stderr +++ b/tests/ui/undocumented_unsafe_blocks.stderr @@ -318,5 +318,47 @@ LL | let bar = unsafe {}; | = help: consider adding a safety comment on the preceding line -error: aborting due to 36 previous errors +error: unsafe block missing a safety comment +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/undocumented_unsafe_blocks.rs:523:9 +======= + --> $DIR/undocumented_unsafe_blocks.rs:519:9 +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= + --> $DIR/undocumented_unsafe_blocks.rs:523:9 +>>>>>>> e2e6a0244 (Addressing reviewer comments) + | +LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> e2e6a0244 (Addressing reviewer comments) +error: unsafe block missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:527:9 + | +LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:531:9 + | +LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: aborting due to 39 previous errors +<<<<<<< HEAD +======= +error: aborting due to 37 previous errors +>>>>>>> 520228b37 (Adding configuration to allow safety comment above stmt containing unsafe block) +======= +>>>>>>> e2e6a0244 (Addressing reviewer comments) diff --git a/tests/ui/undropped_manually_drops.rs b/tests/ui/undropped_manually_drops.rs deleted file mode 100644 index f4cfc92e1cd0..000000000000 --- a/tests/ui/undropped_manually_drops.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![warn(clippy::undropped_manually_drops)] - -struct S; - -fn main() { - let f = std::mem::drop; - let g = std::mem::ManuallyDrop::drop; - let mut manual1 = std::mem::ManuallyDrop::new(S); - let mut manual2 = std::mem::ManuallyDrop::new(S); - let mut manual3 = std::mem::ManuallyDrop::new(S); - let mut manual4 = std::mem::ManuallyDrop::new(S); - - // These lines will not drop `S` and should be linted - drop(std::mem::ManuallyDrop::new(S)); - drop(manual1); - - // FIXME: this line is not linted, though it should be - f(manual2); - - // These lines will drop `S` and should be okay. - unsafe { - std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S)); - std::mem::ManuallyDrop::drop(&mut manual3); - g(&mut manual4); - } -} diff --git a/tests/ui/undropped_manually_drops.stderr b/tests/ui/undropped_manually_drops.stderr deleted file mode 100644 index 92611a9b7df4..000000000000 --- a/tests/ui/undropped_manually_drops.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: the inner value of this ManuallyDrop will not be dropped - --> $DIR/undropped_manually_drops.rs:14:5 - | -LL | drop(std::mem::ManuallyDrop::new(S)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: to drop a `ManuallyDrop`, use std::mem::ManuallyDrop::drop - = note: `-D clippy::undropped-manually-drops` implied by `-D warnings` - -error: the inner value of this ManuallyDrop will not be dropped - --> $DIR/undropped_manually_drops.rs:15:5 - | -LL | drop(manual1); - | ^^^^^^^^^^^^^ - | - = help: to drop a `ManuallyDrop`, use std::mem::ManuallyDrop::drop - -error: aborting due to 2 previous errors - diff --git a/tests/ui/unicode.fixed b/tests/ui/unicode.fixed index 94b4723452fa..9dcdf14bb132 100644 --- a/tests/ui/unicode.fixed +++ b/tests/ui/unicode.fixed @@ -1,5 +1,8 @@ -// run-rustfix -// compile-flags: --test +//@run-rustfix +<<<<<<< HEAD +======= +//@compile-flags: --test +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(dead_code)] #[warn(clippy::invisible_characters)] diff --git a/tests/ui/unicode.rs b/tests/ui/unicode.rs index 6ad0b255b948..f9a815a5180e 100644 --- a/tests/ui/unicode.rs +++ b/tests/ui/unicode.rs @@ -1,5 +1,8 @@ -// run-rustfix -// compile-flags: --test +//@run-rustfix +<<<<<<< HEAD +======= +//@compile-flags: --test +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(dead_code)] #[warn(clippy::invisible_characters)] diff --git a/tests/ui/unicode.stderr b/tests/ui/unicode.stderr index ea74a81451e3..21cc22a778bc 100644 --- a/tests/ui/unicode.stderr +++ b/tests/ui/unicode.stderr @@ -1,5 +1,5 @@ error: invisible character detected - --> $DIR/unicode.rs:7:12 + --> $DIR/unicode.rs:6:12 | LL | print!("Here >​< is a ZWS, and ​another"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{200B}< is a ZWS, and /u{200B}another"` @@ -7,19 +7,19 @@ LL | print!("Here >​< is a ZWS, and ​another"); = note: `-D clippy::invisible-characters` implied by `-D warnings` error: invisible character detected - --> $DIR/unicode.rs:9:12 + --> $DIR/unicode.rs:8:12 | LL | print!("Here >­< is a SHY, and ­another"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{AD}< is a SHY, and /u{AD}another"` error: invisible character detected - --> $DIR/unicode.rs:11:12 + --> $DIR/unicode.rs:10:12 | LL | print!("Here >⁠< is a WJ, and ⁠another"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{2060}< is a WJ, and /u{2060}another"` error: non-NFC Unicode sequence detected - --> $DIR/unicode.rs:17:12 + --> $DIR/unicode.rs:16:12 | LL | print!("̀àh?"); | ^^^^^ help: consider replacing the string with: `"̀àh?"` @@ -27,37 +27,37 @@ LL | print!("̀àh?"); = note: `-D clippy::unicode-not-nfc` implied by `-D warnings` error: literal non-ASCII character detected - --> $DIR/unicode.rs:25:16 + --> $DIR/unicode.rs:24:16 | LL | print!("Üben!"); | ^^^^^^^ help: consider replacing the string with: `"/u{dc}ben!"` | note: the lint level is defined here - --> $DIR/unicode.rs:22:13 + --> $DIR/unicode.rs:21:13 | LL | #![deny(clippy::non_ascii_literal)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: literal non-ASCII character detected - --> $DIR/unicode.rs:31:36 + --> $DIR/unicode.rs:30:36 | LL | const _EMPTY_BLOCK: char = '▱'; | ^^^ help: consider replacing the string with: `'/u{25b1}'` error: literal non-ASCII character detected - --> $DIR/unicode.rs:32:35 + --> $DIR/unicode.rs:31:35 | LL | const _FULL_BLOCK: char = '▰'; | ^^^ help: consider replacing the string with: `'/u{25b0}'` error: literal non-ASCII character detected - --> $DIR/unicode.rs:52:21 + --> $DIR/unicode.rs:51:21 | LL | let _ = "悲しいかな、ここに日本語を書くことはできない。"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"/u{60b2}/u{3057}/u{3044}/u{304b}/u{306a}/u{3001}/u{3053}/u{3053}/u{306b}/u{65e5}/u{672c}/u{8a9e}/u{3092}/u{66f8}/u{304f}/u{3053}/u{3068}/u{306f}/u{3067}/u{304d}/u{306a}/u{3044}/u{3002}"` | note: the lint level is defined here - --> $DIR/unicode.rs:41:17 + --> $DIR/unicode.rs:40:17 | LL | #![deny(clippy::non_ascii_literal)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/uninit.rs b/tests/ui/uninit.rs index c996de89422b..2d567630e15d 100644 --- a/tests/ui/uninit.rs +++ b/tests/ui/uninit.rs @@ -17,10 +17,10 @@ fn main() { // This is OK, because `MaybeUninit` allows uninitialized data. let _: MaybeUninit = unsafe { MaybeUninit::uninit().assume_init() }; - // This is OK, because all constitutent types are uninit-compatible. + // This is OK, because all constituent types are uninit-compatible. let _: (MaybeUninit, MaybeUninit) = unsafe { MaybeUninit::uninit().assume_init() }; - // This is OK, because all constitutent types are uninit-compatible. + // This is OK, because all constituent types are uninit-compatible. let _: (MaybeUninit, [MaybeUninit; 2]) = unsafe { MaybeUninit::uninit().assume_init() }; // This is OK, because our own MaybeUninit is just as fine as the one from core. diff --git a/tests/ui/uninlined_format_args.fixed b/tests/ui/uninlined_format_args.fixed index 3122081a44f9..7662effda893 100644 --- a/tests/ui/uninlined_format_args.fixed +++ b/tests/ui/uninlined_format_args.fixed @@ -1,8 +1,17 @@ -// aux-build:proc_macros.rs -// run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) +//@run-rustfix #![warn(clippy::uninlined_format_args)] #![allow(named_arguments_used_positionally, unused)] -#![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)] +#![allow( + clippy::eq_op, + clippy::format_in_format_args, + clippy::print_literal, + clippy::unnecessary_literal_unwrap +)] extern crate proc_macros; use proc_macros::with_span; diff --git a/tests/ui/uninlined_format_args.rs b/tests/ui/uninlined_format_args.rs index b153ef256e0c..07b2bb6cb40c 100644 --- a/tests/ui/uninlined_format_args.rs +++ b/tests/ui/uninlined_format_args.rs @@ -1,8 +1,17 @@ -// aux-build:proc_macros.rs -// run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) +//@run-rustfix #![warn(clippy::uninlined_format_args)] #![allow(named_arguments_used_positionally, unused)] -#![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)] +#![allow( + clippy::eq_op, + clippy::format_in_format_args, + clippy::print_literal, + clippy::unnecessary_literal_unwrap +)] extern crate proc_macros; use proc_macros::with_span; diff --git a/tests/ui/uninlined_format_args.stderr b/tests/ui/uninlined_format_args.stderr index dc4af6ef42ec..44ca61f008c5 100644 --- a/tests/ui/uninlined_format_args.stderr +++ b/tests/ui/uninlined_format_args.stderr @@ -1,5 +1,5 @@ error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:40:5 + --> $DIR/uninlined_format_args.rs:45:5 | LL | println!("val='{}'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:41:5 + --> $DIR/uninlined_format_args.rs:46:5 | LL | println!("val='{ }'", local_i32); // 3 spaces | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL + println!("val='{local_i32}'"); // 3 spaces | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:42:5 + --> $DIR/uninlined_format_args.rs:47:5 | LL | println!("val='{ }'", local_i32); // tab | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL + println!("val='{local_i32}'"); // tab | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:43:5 + --> $DIR/uninlined_format_args.rs:48:5 | LL | println!("val='{ }'", local_i32); // space+tab | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL + println!("val='{local_i32}'"); // space+tab | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:44:5 + --> $DIR/uninlined_format_args.rs:49:5 | LL | println!("val='{ }'", local_i32); // tab+space | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL + println!("val='{local_i32}'"); // tab+space | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:45:5 + --> $DIR/uninlined_format_args.rs:50:5 | LL | / println!( LL | | "val='{ @@ -70,7 +70,7 @@ LL | | ); | |_____^ error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:50:5 + --> $DIR/uninlined_format_args.rs:55:5 | LL | println!("{}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -82,7 +82,7 @@ LL + println!("{local_i32}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:51:5 + --> $DIR/uninlined_format_args.rs:56:5 | LL | println!("{}", fn_arg); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -94,7 +94,7 @@ LL + println!("{fn_arg}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:52:5 + --> $DIR/uninlined_format_args.rs:57:5 | LL | println!("{:?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -106,7 +106,7 @@ LL + println!("{local_i32:?}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:53:5 + --> $DIR/uninlined_format_args.rs:58:5 | LL | println!("{:#?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL + println!("{local_i32:#?}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:54:5 + --> $DIR/uninlined_format_args.rs:59:5 | LL | println!("{:4}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -130,7 +130,7 @@ LL + println!("{local_i32:4}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:55:5 + --> $DIR/uninlined_format_args.rs:60:5 | LL | println!("{:04}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL + println!("{local_i32:04}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:56:5 + --> $DIR/uninlined_format_args.rs:61:5 | LL | println!("{:<3}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL + println!("{local_i32:<3}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:57:5 + --> $DIR/uninlined_format_args.rs:62:5 | LL | println!("{:#010x}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL + println!("{local_i32:#010x}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:58:5 + --> $DIR/uninlined_format_args.rs:63:5 | LL | println!("{:.1}", local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -178,7 +178,7 @@ LL + println!("{local_f64:.1}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:62:5 + --> $DIR/uninlined_format_args.rs:67:5 | LL | println!("{} {}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -190,7 +190,7 @@ LL + println!("{local_i32} {local_f64}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:64:5 + --> $DIR/uninlined_format_args.rs:69:5 | LL | println!("{}", val); | ^^^^^^^^^^^^^^^^^^^ @@ -202,7 +202,7 @@ LL + println!("{val}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:65:5 + --> $DIR/uninlined_format_args.rs:70:5 | LL | println!("{}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -214,7 +214,7 @@ LL + println!("{val}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:67:5 + --> $DIR/uninlined_format_args.rs:72:5 | LL | println!("val='{/t }'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -226,7 +226,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:68:5 + --> $DIR/uninlined_format_args.rs:73:5 | LL | println!("val='{/n }'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -238,7 +238,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:69:5 + --> $DIR/uninlined_format_args.rs:74:5 | LL | println!("val='{local_i32}'", local_i32 = local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -250,7 +250,7 @@ LL + println!("val='{local_i32}'"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:70:5 + --> $DIR/uninlined_format_args.rs:75:5 | LL | println!("val='{local_i32}'", local_i32 = fn_arg); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -262,7 +262,7 @@ LL + println!("val='{fn_arg}'"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:71:5 + --> $DIR/uninlined_format_args.rs:76:5 | LL | println!("{0}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -274,7 +274,7 @@ LL + println!("{local_i32}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:72:5 + --> $DIR/uninlined_format_args.rs:77:5 | LL | println!("{0:?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -286,7 +286,7 @@ LL + println!("{local_i32:?}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:73:5 + --> $DIR/uninlined_format_args.rs:78:5 | LL | println!("{0:#?}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -298,7 +298,7 @@ LL + println!("{local_i32:#?}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:74:5 + --> $DIR/uninlined_format_args.rs:79:5 | LL | println!("{0:04}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -310,7 +310,7 @@ LL + println!("{local_i32:04}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:75:5 + --> $DIR/uninlined_format_args.rs:80:5 | LL | println!("{0:<3}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -322,7 +322,7 @@ LL + println!("{local_i32:<3}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:76:5 + --> $DIR/uninlined_format_args.rs:81:5 | LL | println!("{0:#010x}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -334,7 +334,7 @@ LL + println!("{local_i32:#010x}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:77:5 + --> $DIR/uninlined_format_args.rs:82:5 | LL | println!("{0:.1}", local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -346,7 +346,7 @@ LL + println!("{local_f64:.1}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:78:5 + --> $DIR/uninlined_format_args.rs:83:5 | LL | println!("{0} {0}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -358,7 +358,7 @@ LL + println!("{local_i32} {local_i32}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:79:5 + --> $DIR/uninlined_format_args.rs:84:5 | LL | println!("{1} {} {0} {}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -370,7 +370,7 @@ LL + println!("{local_f64} {local_i32} {local_i32} {local_f64}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:80:5 + --> $DIR/uninlined_format_args.rs:85:5 | LL | println!("{0} {1}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -382,7 +382,7 @@ LL + println!("{local_i32} {local_f64}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:81:5 + --> $DIR/uninlined_format_args.rs:86:5 | LL | println!("{1} {0}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -394,7 +394,7 @@ LL + println!("{local_f64} {local_i32}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:82:5 + --> $DIR/uninlined_format_args.rs:87:5 | LL | println!("{1} {0} {1} {0}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -406,7 +406,7 @@ LL + println!("{local_f64} {local_i32} {local_f64} {local_i32}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:84:5 + --> $DIR/uninlined_format_args.rs:89:5 | LL | println!("{v}", v = local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -418,7 +418,7 @@ LL + println!("{local_i32}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:85:5 + --> $DIR/uninlined_format_args.rs:90:5 | LL | println!("{local_i32:0$}", width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -430,7 +430,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:86:5 + --> $DIR/uninlined_format_args.rs:91:5 | LL | println!("{local_i32:w$}", w = width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -442,7 +442,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:87:5 + --> $DIR/uninlined_format_args.rs:92:5 | LL | println!("{local_i32:.0$}", prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -454,7 +454,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:88:5 + --> $DIR/uninlined_format_args.rs:93:5 | LL | println!("{local_i32:.p$}", p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -466,7 +466,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:89:5 + --> $DIR/uninlined_format_args.rs:94:5 | LL | println!("{:0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -478,7 +478,7 @@ LL + println!("{val:val$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:90:5 + --> $DIR/uninlined_format_args.rs:95:5 | LL | println!("{0:0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -490,7 +490,7 @@ LL + println!("{val:val$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:91:5 + --> $DIR/uninlined_format_args.rs:96:5 | LL | println!("{:0$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -502,7 +502,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:92:5 + --> $DIR/uninlined_format_args.rs:97:5 | LL | println!("{0:0$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -514,7 +514,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:93:5 + --> $DIR/uninlined_format_args.rs:98:5 | LL | println!("{0:0$.v$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -526,7 +526,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:94:5 + --> $DIR/uninlined_format_args.rs:99:5 | LL | println!("{0:v$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -538,7 +538,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:95:5 + --> $DIR/uninlined_format_args.rs:100:5 | LL | println!("{v:0$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -550,7 +550,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:96:5 + --> $DIR/uninlined_format_args.rs:101:5 | LL | println!("{v:v$.0$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -562,7 +562,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:97:5 + --> $DIR/uninlined_format_args.rs:102:5 | LL | println!("{v:0$.v$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -574,7 +574,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:98:5 + --> $DIR/uninlined_format_args.rs:103:5 | LL | println!("{v:v$.v$}", v = val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -586,7 +586,7 @@ LL + println!("{val:val$.val$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:99:5 + --> $DIR/uninlined_format_args.rs:104:5 | LL | println!("{:0$}", width); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -598,7 +598,7 @@ LL + println!("{width:width$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:100:5 + --> $DIR/uninlined_format_args.rs:105:5 | LL | println!("{:1$}", local_i32, width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -610,7 +610,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:101:5 + --> $DIR/uninlined_format_args.rs:106:5 | LL | println!("{:w$}", w = width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -622,7 +622,7 @@ LL + println!("{width:width$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:102:5 + --> $DIR/uninlined_format_args.rs:107:5 | LL | println!("{:w$}", local_i32, w = width); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -634,7 +634,7 @@ LL + println!("{local_i32:width$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:103:5 + --> $DIR/uninlined_format_args.rs:108:5 | LL | println!("{:.0$}", prec); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -646,7 +646,7 @@ LL + println!("{prec:.prec$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:104:5 + --> $DIR/uninlined_format_args.rs:109:5 | LL | println!("{:.1$}", local_i32, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -658,7 +658,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:105:5 + --> $DIR/uninlined_format_args.rs:110:5 | LL | println!("{:.p$}", p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -670,7 +670,7 @@ LL + println!("{prec:.prec$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:106:5 + --> $DIR/uninlined_format_args.rs:111:5 | LL | println!("{:.p$}", local_i32, p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -682,7 +682,7 @@ LL + println!("{local_i32:.prec$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:107:5 + --> $DIR/uninlined_format_args.rs:112:5 | LL | println!("{:0$.1$}", width, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -694,7 +694,7 @@ LL + println!("{width:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:108:5 + --> $DIR/uninlined_format_args.rs:113:5 | LL | println!("{:0$.w$}", width, w = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -706,7 +706,7 @@ LL + println!("{width:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:109:5 + --> $DIR/uninlined_format_args.rs:114:5 | LL | println!("{:1$.2$}", local_f64, width, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -718,7 +718,7 @@ LL + println!("{local_f64:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:110:5 + --> $DIR/uninlined_format_args.rs:115:5 | LL | println!("{:1$.2$} {0} {1} {2}", local_f64, width, prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -730,7 +730,7 @@ LL + println!("{local_f64:width$.prec$} {local_f64} {width} {prec}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:111:5 + --> $DIR/uninlined_format_args.rs:116:5 | LL | / println!( LL | | "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}", @@ -739,7 +739,7 @@ LL | | ); | |_____^ error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:122:5 + --> $DIR/uninlined_format_args.rs:127:5 | LL | println!("Width = {}, value with width = {:0$}", local_i32, local_f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -751,7 +751,7 @@ LL + println!("Width = {local_i32}, value with width = {local_f64:local_i32$ | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:123:5 + --> $DIR/uninlined_format_args.rs:128:5 | LL | println!("{:w$.p$}", local_i32, w = width, p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -763,7 +763,7 @@ LL + println!("{local_i32:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:124:5 + --> $DIR/uninlined_format_args.rs:129:5 | LL | println!("{:w$.p$}", w = width, p = prec); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -775,7 +775,7 @@ LL + println!("{width:width$.prec$}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:143:5 + --> $DIR/uninlined_format_args.rs:148:5 | LL | / println!( LL | | "{}", @@ -785,7 +785,7 @@ LL | | ); | |_____^ error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:148:5 + --> $DIR/uninlined_format_args.rs:153:5 | LL | println!("{}", /* comment with a comma , in it */ val); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -797,7 +797,7 @@ LL + println!("{val}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:154:9 + --> $DIR/uninlined_format_args.rs:159:9 | LL | panic!("p1 {}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -809,7 +809,7 @@ LL + panic!("p1 {local_i32}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:157:9 + --> $DIR/uninlined_format_args.rs:162:9 | LL | panic!("p2 {0}", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -821,7 +821,7 @@ LL + panic!("p2 {local_i32}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:160:9 + --> $DIR/uninlined_format_args.rs:165:9 | LL | panic!("p3 {local_i32}", local_i32 = local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -833,7 +833,7 @@ LL + panic!("p3 {local_i32}"); | error: variables can be used directly in the `format!` string - --> $DIR/uninlined_format_args.rs:180:5 + --> $DIR/uninlined_format_args.rs:185:5 | LL | println!("expand='{}'", local_i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/uninlined_format_args_panic.edition2018.fixed b/tests/ui/uninlined_format_args_panic.edition2018.fixed index 52b5343c351e..559050b3df62 100644 --- a/tests/ui/uninlined_format_args_panic.edition2018.fixed +++ b/tests/ui/uninlined_format_args_panic.edition2018.fixed @@ -1,7 +1,7 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::uninlined_format_args)] diff --git a/tests/ui/uninlined_format_args_panic.edition2021.fixed b/tests/ui/uninlined_format_args_panic.edition2021.fixed index ee72065e28ab..3a753b49caf3 100644 --- a/tests/ui/uninlined_format_args_panic.edition2021.fixed +++ b/tests/ui/uninlined_format_args_panic.edition2021.fixed @@ -1,7 +1,7 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::uninlined_format_args)] diff --git a/tests/ui/uninlined_format_args_panic.rs b/tests/ui/uninlined_format_args_panic.rs index b4a0a0f496e4..83fbb9afd2a1 100644 --- a/tests/ui/uninlined_format_args_panic.rs +++ b/tests/ui/uninlined_format_args_panic.rs @@ -1,7 +1,7 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::uninlined_format_args)] diff --git a/tests/ui/unit_arg.rs b/tests/ui/unit_arg.rs index 674ae4f1df97..122a7c202bc3 100644 --- a/tests/ui/unit_arg.rs +++ b/tests/ui/unit_arg.rs @@ -1,4 +1,8 @@ -// aux-build: proc_macros.rs +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::unit_arg)] #![allow(unused_must_use, unused_variables)] #![allow( diff --git a/tests/ui/unit_arg_empty_blocks.fixed b/tests/ui/unit_arg_empty_blocks.fixed index 5787471a32ca..8c065115a74e 100644 --- a/tests/ui/unit_arg_empty_blocks.fixed +++ b/tests/ui/unit_arg_empty_blocks.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unit_arg)] #![allow(unused_must_use, unused_variables)] #![allow(clippy::no_effect, clippy::uninlined_format_args)] diff --git a/tests/ui/unit_arg_empty_blocks.rs b/tests/ui/unit_arg_empty_blocks.rs index 6a42c2ccf42b..af166b56ff48 100644 --- a/tests/ui/unit_arg_empty_blocks.rs +++ b/tests/ui/unit_arg_empty_blocks.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unit_arg)] #![allow(unused_must_use, unused_variables)] #![allow(clippy::no_effect, clippy::uninlined_format_args)] diff --git a/tests/ui/unit_cmp.rs b/tests/ui/unit_cmp.rs index 3d271104361b..fc75f548a1bc 100644 --- a/tests/ui/unit_cmp.rs +++ b/tests/ui/unit_cmp.rs @@ -2,7 +2,8 @@ #![allow( clippy::no_effect, clippy::unnecessary_operation, - clippy::derive_partial_eq_without_eq + clippy::derive_partial_eq_without_eq, + clippy::needless_if )] #[derive(PartialEq)] diff --git a/tests/ui/unit_cmp.stderr b/tests/ui/unit_cmp.stderr index 41cf19ae685e..79c890d644cd 100644 --- a/tests/ui/unit_cmp.stderr +++ b/tests/ui/unit_cmp.stderr @@ -1,5 +1,5 @@ error: ==-comparison of unit values detected. This will always be true - --> $DIR/unit_cmp.rs:16:8 + --> $DIR/unit_cmp.rs:17:8 | LL | if { | ________^ @@ -12,7 +12,7 @@ LL | | } {} = note: `-D clippy::unit-cmp` implied by `-D warnings` error: >-comparison of unit values detected. This will always be false - --> $DIR/unit_cmp.rs:22:8 + --> $DIR/unit_cmp.rs:23:8 | LL | if { | ________^ @@ -23,7 +23,7 @@ LL | | } {} | |_____^ error: `assert_eq` of unit values detected. This will always succeed - --> $DIR/unit_cmp.rs:28:5 + --> $DIR/unit_cmp.rs:29:5 | LL | / assert_eq!( LL | | { @@ -35,7 +35,7 @@ LL | | ); | |_____^ error: `debug_assert_eq` of unit values detected. This will always succeed - --> $DIR/unit_cmp.rs:36:5 + --> $DIR/unit_cmp.rs:37:5 | LL | / debug_assert_eq!( LL | | { @@ -47,7 +47,7 @@ LL | | ); | |_____^ error: `assert_ne` of unit values detected. This will always fail - --> $DIR/unit_cmp.rs:45:5 + --> $DIR/unit_cmp.rs:46:5 | LL | / assert_ne!( LL | | { @@ -59,7 +59,7 @@ LL | | ); | |_____^ error: `debug_assert_ne` of unit values detected. This will always fail - --> $DIR/unit_cmp.rs:53:5 + --> $DIR/unit_cmp.rs:54:5 | LL | / debug_assert_ne!( LL | | { diff --git a/tests/ui/unit_return_expecting_ord.rs b/tests/ui/unit_return_expecting_ord.rs index bdb4710cc697..f2a9694f99e5 100644 --- a/tests/ui/unit_return_expecting_ord.rs +++ b/tests/ui/unit_return_expecting_ord.rs @@ -1,6 +1,7 @@ #![warn(clippy::unit_return_expecting_ord)] #![allow(clippy::needless_return)] #![allow(clippy::unused_unit)] +#![allow(clippy::useless_vec)] #![feature(is_sorted)] struct Struct { diff --git a/tests/ui/unit_return_expecting_ord.stderr b/tests/ui/unit_return_expecting_ord.stderr index 1d9564ce225e..3a295af55eac 100644 --- a/tests/ui/unit_return_expecting_ord.stderr +++ b/tests/ui/unit_return_expecting_ord.stderr @@ -1,36 +1,36 @@ error: this closure returns the unit type which also implements Ord - --> $DIR/unit_return_expecting_ord.rs:18:25 + --> $DIR/unit_return_expecting_ord.rs:19:25 | LL | structs.sort_by_key(|s| { | ^^^ | help: probably caused by this trailing semicolon - --> $DIR/unit_return_expecting_ord.rs:19:24 + --> $DIR/unit_return_expecting_ord.rs:20:24 | LL | double(s.field); | ^ = note: `-D clippy::unit-return-expecting-ord` implied by `-D warnings` error: this closure returns the unit type which also implements PartialOrd - --> $DIR/unit_return_expecting_ord.rs:22:30 + --> $DIR/unit_return_expecting_ord.rs:23:30 | LL | structs.is_sorted_by_key(|s| { | ^^^ | help: probably caused by this trailing semicolon - --> $DIR/unit_return_expecting_ord.rs:23:24 + --> $DIR/unit_return_expecting_ord.rs:24:24 | LL | double(s.field); | ^ error: this closure returns the unit type which also implements PartialOrd - --> $DIR/unit_return_expecting_ord.rs:25:30 + --> $DIR/unit_return_expecting_ord.rs:26:30 | LL | structs.is_sorted_by_key(|s| { | ^^^ error: this closure returns the unit type which also implements Ord - --> $DIR/unit_return_expecting_ord.rs:35:25 + --> $DIR/unit_return_expecting_ord.rs:36:25 | LL | structs.sort_by_key(|s| unit(s.field)); | ^^^ diff --git a/tests/ui/unknown_clippy_lints.fixed b/tests/ui/unknown_clippy_lints.fixed index 4249ff8a958d..debc7e152e73 100644 --- a/tests/ui/unknown_clippy_lints.fixed +++ b/tests/ui/unknown_clippy_lints.fixed @@ -1,16 +1,16 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::pedantic)] // Should suggest lowercase #![allow(clippy::all)] -#![warn(clippy::cmp_nan)] +#![warn(clippy::cmp_owned)] // Should suggest similar clippy lint name #[warn(clippy::if_not_else)] #[warn(clippy::unnecessary_cast)] #[warn(clippy::useless_transmute)] // Shouldn't suggest rustc lint name(`dead_code`) -#[warn(clippy::drop_copy)] +#[warn(clippy::eq_op)] // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`) #[warn(clippy::unused_self)] // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`) diff --git a/tests/ui/unknown_clippy_lints.rs b/tests/ui/unknown_clippy_lints.rs index 5db345f54441..16140fd10791 100644 --- a/tests/ui/unknown_clippy_lints.rs +++ b/tests/ui/unknown_clippy_lints.rs @@ -1,9 +1,9 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::pedantic)] // Should suggest lowercase #![allow(clippy::All)] -#![warn(clippy::CMP_NAN)] +#![warn(clippy::CMP_OWNED)] // Should suggest similar clippy lint name #[warn(clippy::if_not_els)] diff --git a/tests/ui/unknown_clippy_lints.stderr b/tests/ui/unknown_clippy_lints.stderr index 421bf5ffa9a7..880673eef3e4 100644 --- a/tests/ui/unknown_clippy_lints.stderr +++ b/tests/ui/unknown_clippy_lints.stderr @@ -6,11 +6,11 @@ LL | #![allow(clippy::All)] | = note: `-D unknown-lints` implied by `-D warnings` -error: unknown lint: `clippy::CMP_NAN` +error: unknown lint: `clippy::CMP_OWNED` --> $DIR/unknown_clippy_lints.rs:6:9 | -LL | #![warn(clippy::CMP_NAN)] - | ^^^^^^^^^^^^^^^ help: did you mean: `clippy::cmp_nan` +LL | #![warn(clippy::CMP_OWNED)] + | ^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::cmp_owned` error: unknown lint: `clippy::if_not_els` --> $DIR/unknown_clippy_lints.rs:9:8 @@ -34,7 +34,7 @@ error: unknown lint: `clippy::dead_cod` --> $DIR/unknown_clippy_lints.rs:13:8 | LL | #[warn(clippy::dead_cod)] - | ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::drop_copy` + | ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::eq_op` error: unknown lint: `clippy::unused_colle` --> $DIR/unknown_clippy_lints.rs:15:8 diff --git a/tests/ui/unnecessary_box_returns.rs b/tests/ui/unnecessary_box_returns.rs index fe60d929759b..4b5feefee70b 100644 --- a/tests/ui/unnecessary_box_returns.rs +++ b/tests/ui/unnecessary_box_returns.rs @@ -54,6 +54,31 @@ fn string() -> String { String::from("Hello, world") } +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) +struct Huge([u8; 500]); +struct HasHuge(Box); + +impl HasHuge { + // don't lint: The size of `Huge` is very large + fn into_huge(self) -> Box { + self.0 + } +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 6b95029f1 (Merge commit '83e42a2337dadac915c956d125f1d69132f36425' into clippyup) +======= +>>>>>>> a1b75c510 (Merge commit 'a3ed905928a03b6e433d0b429190bf3a847128b3' into clippyup) +======= +>>>>>>> 4bc68f9c6 (Add size-parameter to unecessary_box_returns) fn main() { // don't lint: this is a closure let a = || -> Box { Box::new(5) }; diff --git a/tests/ui/unnecessary_cast.fixed b/tests/ui/unnecessary_cast.fixed index 2f7e2997e739..7343142b7948 100644 --- a/tests/ui/unnecessary_cast.fixed +++ b/tests/ui/unnecessary_cast.fixed @@ -1,13 +1,71 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +//@aux-build:extern_fake_libc.rs +======= +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::unnecessary_cast)] #![allow( - unused_must_use, +<<<<<<< HEAD +<<<<<<< HEAD +======= + unused, +>>>>>>> d2de5769a (add generics in test) +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) clippy::borrow_as_ptr, clippy::no_effect, clippy::nonstandard_macro_braces, - clippy::unnecessary_operation + clippy::unnecessary_operation, + nonstandard_style, + unused )] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) +extern crate extern_fake_libc; + +type PtrConstU8 = *const u8; +type PtrMutU8 = *mut u8; + +fn owo(ptr: *const T) -> *const T { + ptr +} + +fn uwu(ptr: *const T) -> *const U { + ptr as *const U +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) +mod fake_libc { + type pid_t = i32; + pub unsafe fn getpid() -> pid_t { + pid_t::from(0) + } + // Make sure a where clause does not break it + pub fn getpid_SAFE_TRUTH(t: &T) -> pid_t + where + T: Clone, + { + t; + unsafe { getpid() } + } +} + +<<<<<<< HEAD +======= +type PtrConstU8 = *const u8; +type PtrMutU8 = *mut u8; + +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= +>>>>>>> d2de5769a (add generics in test) +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) #[rustfmt::skip] fn main() { // Test cast_unnecessary @@ -22,6 +80,47 @@ fn main() { 1_i32; 1_f32; +<<<<<<< HEAD +<<<<<<< HEAD + let _: *mut u8 = [1u8, 2].as_ptr() as *mut u8; + +======= +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + let _: *mut u8 = [1u8, 2].as_ptr() as *mut u8; + +>>>>>>> d2de5769a (add generics in test) + [1u8, 2].as_ptr(); + [1u8, 2].as_ptr() as *mut u8; + [1u8, 2].as_mut_ptr(); + [1u8, 2].as_mut_ptr() as *const u8; + [1u8, 2].as_ptr() as PtrConstU8; + [1u8, 2].as_ptr() as PtrMutU8; + [1u8, 2].as_mut_ptr() as PtrMutU8; + [1u8, 2].as_mut_ptr() as PtrConstU8; + let _: *const u8 = [1u8, 2].as_ptr() as _; + let _: *mut u8 = [1u8, 2].as_mut_ptr() as _; +<<<<<<< HEAD +<<<<<<< HEAD + let _: *const u8 = [1u8, 2].as_ptr() as *const _; + let _: *mut u8 = [1u8, 2].as_mut_ptr() as *mut _; + + owo::([1u32].as_ptr()); + uwu::([1u32].as_ptr()); + // this will not lint in the function body even though they have the same type, instead here + uwu::([1u32].as_ptr()); +======= +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + let _: *const u8 = [1u8, 2].as_ptr() as *const _; + let _: *mut u8 = [1u8, 2].as_mut_ptr() as *mut _; +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) + + owo::([1u32].as_ptr()); + uwu::([1u32].as_ptr()); + // this will not lint in the function body even though they have the same type, instead here + uwu::([1u32].as_ptr()); + // macro version macro_rules! foo { ($a:ident, $b:ident) => { @@ -35,12 +134,57 @@ fn main() { foo!(b, f32); foo!(c, f64); + // do not lint cast from cfg-dependant type + let x = 0 as std::ffi::c_ulong; + let y = x as u64; + let x: std::ffi::c_ulong = 0; + let y = x as u64; + // do not lint cast to cfg-dependant type - 1 as std::os::raw::c_char; + let x = 1 as std::os::raw::c_char; + let y = x as u64; // do not lint cast to alias type 1 as I32Alias; &1 as &I32Alias; + // or from + let x: I32Alias = 1; + let y = x as u64; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + fake_libc::getpid_SAFE_TRUTH(&0u32) as i32; + extern_fake_libc::getpid_SAFE_TRUTH() as i32; + let pid = unsafe { fake_libc::getpid() }; + pid as i32; +<<<<<<< HEAD + + let i8_ptr: *const i8 = &1; + let u8_ptr: *const u8 = &1; + + // cfg dependant pointees + i8_ptr as *const std::os::raw::c_char; + u8_ptr as *const std::os::raw::c_char; + + // type aliased pointees + i8_ptr as *const std::ffi::c_char; + u8_ptr as *const std::ffi::c_char; +======= +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + + let i8_ptr: *const i8 = &1; + let u8_ptr: *const u8 = &1; + + // cfg dependant pointees + i8_ptr as *const std::os::raw::c_char; + u8_ptr as *const std::os::raw::c_char; + + // type aliased pointees + i8_ptr as *const std::ffi::c_char; + u8_ptr as *const std::ffi::c_char; // issue #9960 macro_rules! bind_var { diff --git a/tests/ui/unnecessary_cast.rs b/tests/ui/unnecessary_cast.rs index 54dd46ba59f1..a16bd2b6cca1 100644 --- a/tests/ui/unnecessary_cast.rs +++ b/tests/ui/unnecessary_cast.rs @@ -1,13 +1,71 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +//@aux-build:extern_fake_libc.rs +======= +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::unnecessary_cast)] #![allow( - unused_must_use, +<<<<<<< HEAD +<<<<<<< HEAD +======= + unused, +>>>>>>> d2de5769a (add generics in test) +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) clippy::borrow_as_ptr, clippy::no_effect, clippy::nonstandard_macro_braces, - clippy::unnecessary_operation + clippy::unnecessary_operation, + nonstandard_style, + unused )] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) +extern crate extern_fake_libc; + +type PtrConstU8 = *const u8; +type PtrMutU8 = *mut u8; + +fn owo(ptr: *const T) -> *const T { + ptr as *const T +} + +fn uwu(ptr: *const T) -> *const U { + ptr as *const U +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) +mod fake_libc { + type pid_t = i32; + pub unsafe fn getpid() -> pid_t { + pid_t::from(0) + } + // Make sure a where clause does not break it + pub fn getpid_SAFE_TRUTH(t: &T) -> pid_t + where + T: Clone, + { + t; + unsafe { getpid() } + } +} + +<<<<<<< HEAD +======= +type PtrConstU8 = *const u8; +type PtrMutU8 = *mut u8; + +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= +>>>>>>> d2de5769a (add generics in test) +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) #[rustfmt::skip] fn main() { // Test cast_unnecessary @@ -22,6 +80,47 @@ fn main() { 1_i32 as i32; 1_f32 as f32; +<<<<<<< HEAD +<<<<<<< HEAD + let _: *mut u8 = [1u8, 2].as_ptr() as *const u8 as *mut u8; + +======= +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + let _: *mut u8 = [1u8, 2].as_ptr() as *const u8 as *mut u8; + +>>>>>>> d2de5769a (add generics in test) + [1u8, 2].as_ptr() as *const u8; + [1u8, 2].as_ptr() as *mut u8; + [1u8, 2].as_mut_ptr() as *mut u8; + [1u8, 2].as_mut_ptr() as *const u8; + [1u8, 2].as_ptr() as PtrConstU8; + [1u8, 2].as_ptr() as PtrMutU8; + [1u8, 2].as_mut_ptr() as PtrMutU8; + [1u8, 2].as_mut_ptr() as PtrConstU8; + let _: *const u8 = [1u8, 2].as_ptr() as _; + let _: *mut u8 = [1u8, 2].as_mut_ptr() as _; +<<<<<<< HEAD +<<<<<<< HEAD + let _: *const u8 = [1u8, 2].as_ptr() as *const _; + let _: *mut u8 = [1u8, 2].as_mut_ptr() as *mut _; + + owo::([1u32].as_ptr()) as *const u32; + uwu::([1u32].as_ptr()) as *const u8; + // this will not lint in the function body even though they have the same type, instead here + uwu::([1u32].as_ptr()) as *const u32; +======= +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + let _: *const u8 = [1u8, 2].as_ptr() as *const _; + let _: *mut u8 = [1u8, 2].as_mut_ptr() as *mut _; +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) + + owo::([1u32].as_ptr()) as *const u32; + uwu::([1u32].as_ptr()) as *const u8; + // this will not lint in the function body even though they have the same type, instead here + uwu::([1u32].as_ptr()) as *const u32; + // macro version macro_rules! foo { ($a:ident, $b:ident) => { @@ -35,12 +134,57 @@ fn main() { foo!(b, f32); foo!(c, f64); + // do not lint cast from cfg-dependant type + let x = 0 as std::ffi::c_ulong; + let y = x as u64; + let x: std::ffi::c_ulong = 0; + let y = x as u64; + // do not lint cast to cfg-dependant type - 1 as std::os::raw::c_char; + let x = 1 as std::os::raw::c_char; + let y = x as u64; // do not lint cast to alias type 1 as I32Alias; &1 as &I32Alias; + // or from + let x: I32Alias = 1; + let y = x as u64; +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + fake_libc::getpid_SAFE_TRUTH(&0u32) as i32; + extern_fake_libc::getpid_SAFE_TRUTH() as i32; + let pid = unsafe { fake_libc::getpid() }; + pid as i32; +<<<<<<< HEAD + + let i8_ptr: *const i8 = &1; + let u8_ptr: *const u8 = &1; + + // cfg dependant pointees + i8_ptr as *const std::os::raw::c_char; + u8_ptr as *const std::os::raw::c_char; + + // type aliased pointees + i8_ptr as *const std::ffi::c_char; + u8_ptr as *const std::ffi::c_char; +======= +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + + let i8_ptr: *const i8 = &1; + let u8_ptr: *const u8 = &1; + + // cfg dependant pointees + i8_ptr as *const std::os::raw::c_char; + u8_ptr as *const std::os::raw::c_char; + + // type aliased pointees + i8_ptr as *const std::ffi::c_char; + u8_ptr as *const std::ffi::c_char; // issue #9960 macro_rules! bind_var { diff --git a/tests/ui/unnecessary_cast.stderr b/tests/ui/unnecessary_cast.stderr index fcee4ee2a65c..460999b75b80 100644 --- a/tests/ui/unnecessary_cast.stderr +++ b/tests/ui/unnecessary_cast.stderr @@ -1,190 +1,1065 @@ +<<<<<<< HEAD +<<<<<<< HEAD +error: casting raw pointers to the same type and constness is unnecessary (`*const T` -> `*const T`) + --> $DIR/unnecessary_cast.rs:19:5 +======= error: casting integer literal to `i32` is unnecessary - --> $DIR/unnecessary_cast.rs:14:5 + --> $DIR/unnecessary_cast.rs:17:5 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= +error: casting raw pointers to the same type and constness is unnecessary (`*const T` -> `*const T`) +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:15:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:19:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | -LL | 1i32 as i32; - | ^^^^^^^^^^^ help: try: `1_i32` +LL | ptr as *const T + | ^^^^^^^^^^^^^^^ help: try: `ptr` | = note: `-D clippy::unnecessary-cast` implied by `-D warnings` +error: casting integer literal to `i32` is unnecessary +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:44:5 +======= + --> $DIR/unnecessary_cast.rs:25:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:44:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + | +LL | 1i32 as i32; + | ^^^^^^^^^^^ help: try: `1_i32` + error: casting float literal to `f32` is unnecessary - --> $DIR/unnecessary_cast.rs:15:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:45:5 +======= + --> $DIR/unnecessary_cast.rs:18:5 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:26:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:45:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 1f32 as f32; | ^^^^^^^^^^^ help: try: `1_f32` error: casting to the same type is unnecessary (`bool` -> `bool`) - --> $DIR/unnecessary_cast.rs:16:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:46:5 +======= + --> $DIR/unnecessary_cast.rs:19:5 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:27:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:46:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | false as bool; | ^^^^^^^^^^^^^ help: try: `false` error: casting integer literal to `i32` is unnecessary - --> $DIR/unnecessary_cast.rs:19:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:49:5 +======= + --> $DIR/unnecessary_cast.rs:22:5 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:30:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:49:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | -1_i32 as i32; | ^^^^^^^^^^^^^ help: try: `-1_i32` error: casting integer literal to `i32` is unnecessary - --> $DIR/unnecessary_cast.rs:20:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:50:5 +======= + --> $DIR/unnecessary_cast.rs:23:5 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:31:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:50:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | - 1_i32 as i32; | ^^^^^^^^^^^^^^ help: try: `- 1_i32` error: casting float literal to `f32` is unnecessary - --> $DIR/unnecessary_cast.rs:21:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:51:5 +======= + --> $DIR/unnecessary_cast.rs:24:5 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:32:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:51:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | -1f32 as f32; | ^^^^^^^^^^^^ help: try: `-1_f32` error: casting integer literal to `i32` is unnecessary - --> $DIR/unnecessary_cast.rs:22:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:52:5 +======= + --> $DIR/unnecessary_cast.rs:25:5 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:33:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:52:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 1_i32 as i32; | ^^^^^^^^^^^^ help: try: `1_i32` error: casting float literal to `f32` is unnecessary - --> $DIR/unnecessary_cast.rs:23:5 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:53:5 +======= + --> $DIR/unnecessary_cast.rs:26:5 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:34:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:53:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 1_f32 as f32; | ^^^^^^^^^^^^ help: try: `1_f32` +error: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`) +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:55:22 +======= + --> $DIR/unnecessary_cast.rs:36:22 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:55:22 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + | +LL | let _: *mut u8 = [1u8, 2].as_ptr() as *const u8 as *mut u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_ptr()` + +error: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`) +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:57:5 +======= + --> $DIR/unnecessary_cast.rs:28:5 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:38:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:57:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + | +LL | [1u8, 2].as_ptr() as *const u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_ptr()` + +error: casting raw pointers to the same type and constness is unnecessary (`*mut u8` -> `*mut u8`) +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:59:5 +======= + --> $DIR/unnecessary_cast.rs:30:5 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:40:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:59:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + | +LL | [1u8, 2].as_mut_ptr() as *mut u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_mut_ptr()` + +<<<<<<< HEAD +<<<<<<< HEAD +error: casting raw pointers to the same type and constness is unnecessary (`*const u32` -> `*const u32`) + --> $DIR/unnecessary_cast.rs:70:5 +<<<<<<< HEAD +======= +error: casting raw pointers to the same type and constness is unnecessary (`*const u32` -> `*const u32`) +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:49:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:51:5 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + | +LL | owo::([1u32].as_ptr()) as *const u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `owo::([1u32].as_ptr())` + +error: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`) +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:71:5 +======= + --> $DIR/unnecessary_cast.rs:50:5 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:52:5 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:71:5 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + | +LL | uwu::([1u32].as_ptr()) as *const u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `uwu::([1u32].as_ptr())` + +<<<<<<< HEAD +<<<<<<< HEAD +error: casting raw pointers to the same type and constness is unnecessary (`*const u32` -> `*const u32`) + --> $DIR/unnecessary_cast.rs:73:5 +<<<<<<< HEAD +======= +error: casting raw pointers to the same type and constness is unnecessary (`*const u32` -> `*const u32`) +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:52:5 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:54:5 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) + | +LL | uwu::([1u32].as_ptr()) as *const u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `uwu::([1u32].as_ptr())` + +<<<<<<< HEAD +error: casting integer literal to `f32` is unnecessary +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:139:9 +======= error: casting integer literal to `f32` is unnecessary - --> $DIR/unnecessary_cast.rs:64:9 + --> $DIR/unnecessary_cast.rs:78:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= +error: casting integer literal to `f32` is unnecessary + --> $DIR/unnecessary_cast.rs:91:9 +>>>>>>> d2de5769a (add generics in test) +======= +error: casting integer literal to `f32` is unnecessary +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:93:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:106:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:117:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:116:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:139:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 100 as f32; | ^^^^^^^^^^ help: try: `100_f32` error: casting integer literal to `f64` is unnecessary - --> $DIR/unnecessary_cast.rs:65:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:140:9 +======= + --> $DIR/unnecessary_cast.rs:79:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:92:9 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:94:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:107:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:118:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:117:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:140:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 100 as f64; | ^^^^^^^^^^ help: try: `100_f64` error: casting integer literal to `f64` is unnecessary - --> $DIR/unnecessary_cast.rs:66:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:141:9 +======= + --> $DIR/unnecessary_cast.rs:80:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:93:9 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:95:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:108:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:119:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:118:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:141:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 100_i32 as f64; | ^^^^^^^^^^^^^^ help: try: `100_f64` error: casting integer literal to `f32` is unnecessary - --> $DIR/unnecessary_cast.rs:67:17 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:142:17 +======= + --> $DIR/unnecessary_cast.rs:81:17 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:94:17 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:96:17 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:109:17 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:120:17 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:119:17 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:142:17 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | let _ = -100 as f32; | ^^^^^^^^^^^ help: try: `-100_f32` error: casting integer literal to `f64` is unnecessary - --> $DIR/unnecessary_cast.rs:68:17 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:143:17 +======= + --> $DIR/unnecessary_cast.rs:82:17 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:95:17 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:97:17 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:110:17 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:121:17 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:120:17 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:143:17 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | let _ = -100 as f64; | ^^^^^^^^^^^ help: try: `-100_f64` error: casting integer literal to `f64` is unnecessary - --> $DIR/unnecessary_cast.rs:69:17 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:144:17 +======= + --> $DIR/unnecessary_cast.rs:83:17 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:96:17 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:98:17 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:111:17 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:122:17 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:121:17 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:144:17 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | let _ = -100_i32 as f64; | ^^^^^^^^^^^^^^^ help: try: `-100_f64` error: casting float literal to `f32` is unnecessary - --> $DIR/unnecessary_cast.rs:70:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:145:9 +======= + --> $DIR/unnecessary_cast.rs:84:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:97:9 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:99:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:112:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:123:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:122:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:145:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 100. as f32; | ^^^^^^^^^^^ help: try: `100_f32` error: casting float literal to `f64` is unnecessary - --> $DIR/unnecessary_cast.rs:71:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:146:9 +======= + --> $DIR/unnecessary_cast.rs:85:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:98:9 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:100:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:113:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:124:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:123:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:146:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 100. as f64; | ^^^^^^^^^^^ help: try: `100_f64` error: casting integer literal to `u32` is unnecessary - --> $DIR/unnecessary_cast.rs:83:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:158:9 +======= + --> $DIR/unnecessary_cast.rs:97:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:110:9 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:112:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:125:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:136:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:135:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:158:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 1 as u32; | ^^^^^^^^ help: try: `1_u32` error: casting integer literal to `i32` is unnecessary - --> $DIR/unnecessary_cast.rs:84:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:159:9 +======= + --> $DIR/unnecessary_cast.rs:98:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:111:9 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:113:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:126:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:137:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:136:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:159:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 0x10 as i32; | ^^^^^^^^^^^ help: try: `0x10_i32` error: casting integer literal to `usize` is unnecessary - --> $DIR/unnecessary_cast.rs:85:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:160:9 +======= + --> $DIR/unnecessary_cast.rs:99:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:112:9 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:114:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:127:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:138:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:137:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:160:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 0b10 as usize; | ^^^^^^^^^^^^^ help: try: `0b10_usize` error: casting integer literal to `u16` is unnecessary - --> $DIR/unnecessary_cast.rs:86:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:161:9 +======= + --> $DIR/unnecessary_cast.rs:100:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:113:9 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:115:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:128:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:139:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:138:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:161:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 0o73 as u16; | ^^^^^^^^^^^ help: try: `0o73_u16` error: casting integer literal to `u32` is unnecessary - --> $DIR/unnecessary_cast.rs:87:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:162:9 +======= + --> $DIR/unnecessary_cast.rs:101:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:114:9 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:116:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:129:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:140:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:139:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:162:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 1_000_000_000 as u32; | ^^^^^^^^^^^^^^^^^^^^ help: try: `1_000_000_000_u32` error: casting float literal to `f64` is unnecessary - --> $DIR/unnecessary_cast.rs:89:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:164:9 +======= + --> $DIR/unnecessary_cast.rs:103:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:116:9 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:118:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:131:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:142:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:141:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:164:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 1.0 as f64; | ^^^^^^^^^^ help: try: `1.0_f64` error: casting float literal to `f32` is unnecessary - --> $DIR/unnecessary_cast.rs:90:9 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:165:9 +======= + --> $DIR/unnecessary_cast.rs:104:9 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:117:9 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:119:9 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:132:9 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:143:9 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:142:9 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:165:9 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | 0.5 as f32; | ^^^^^^^^^^ help: try: `0.5_f32` error: casting integer literal to `i32` is unnecessary - --> $DIR/unnecessary_cast.rs:94:17 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:169:17 +======= + --> $DIR/unnecessary_cast.rs:108:17 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:121:17 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:123:17 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:136:17 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:147:17 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:146:17 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:169:17 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | let _ = -1 as i32; | ^^^^^^^^^ help: try: `-1_i32` error: casting float literal to `f32` is unnecessary - --> $DIR/unnecessary_cast.rs:95:17 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:170:17 +======= + --> $DIR/unnecessary_cast.rs:109:17 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:122:17 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:124:17 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:137:17 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:148:17 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:147:17 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:170:17 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | let _ = -1.0 as f32; | ^^^^^^^^^^^ help: try: `-1.0_f32` error: casting to the same type is unnecessary (`i32` -> `i32`) - --> $DIR/unnecessary_cast.rs:101:18 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:176:18 +======= + --> $DIR/unnecessary_cast.rs:115:18 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:128:18 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:130:18 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:143:18 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:154:18 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:153:18 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:176:18 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | let _ = &(x as i32); | ^^^^^^^^^^ help: try: `{ x }` error: casting integer literal to `i32` is unnecessary - --> $DIR/unnecessary_cast.rs:107:22 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:182:22 +======= + --> $DIR/unnecessary_cast.rs:121:22 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:134:22 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:136:22 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:149:22 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:160:22 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:159:22 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:182:22 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | let _: i32 = -(1) as i32; | ^^^^^^^^^^^ help: try: `-1_i32` error: casting integer literal to `i64` is unnecessary - --> $DIR/unnecessary_cast.rs:109:22 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:184:22 +======= + --> $DIR/unnecessary_cast.rs:123:22 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:136:22 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:138:22 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:151:22 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:162:22 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:161:22 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:184:22 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | let _: i64 = -(1) as i64; | ^^^^^^^^^^^ help: try: `-1_i64` error: casting float literal to `f64` is unnecessary - --> $DIR/unnecessary_cast.rs:116:22 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:191:22 +======= + --> $DIR/unnecessary_cast.rs:130:22 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:143:22 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:145:22 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:158:22 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:169:22 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:168:22 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:191:22 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | let _: f64 = (-8.0 as f64).exp(); | ^^^^^^^^^^^^^ help: try: `(-8.0_f64)` error: casting float literal to `f64` is unnecessary - --> $DIR/unnecessary_cast.rs:118:23 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:193:23 +======= + --> $DIR/unnecessary_cast.rs:132:23 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:145:23 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:147:23 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:160:23 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:171:23 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:170:23 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:193:23 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior | ^^^^^^^^^^^^ help: try: `8.0_f64` error: casting to the same type is unnecessary (`f32` -> `f32`) - --> $DIR/unnecessary_cast.rs:126:20 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_cast.rs:201:20 +======= + --> $DIR/unnecessary_cast.rs:140:20 +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= + --> $DIR/unnecessary_cast.rs:153:20 +>>>>>>> d2de5769a (add generics in test) +======= + --> $DIR/unnecessary_cast.rs:155:20 +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) +======= + --> $DIR/unnecessary_cast.rs:168:20 +>>>>>>> 4346c992c (Ignore more pointer types in `unnecessary_cast`) +======= + --> $DIR/unnecessary_cast.rs:179:20 +>>>>>>> 4c7bc1785 (ignore more type aliases in unnecessary_cast) +======= + --> $DIR/unnecessary_cast.rs:178:20 +>>>>>>> 382244133 (Update unnecessary_cast.stderr) +======= + --> $DIR/unnecessary_cast.rs:201:20 +>>>>>>> 357e80ea0 (Ignore more type aliases in `unnecessary_cast`) | LL | let _num = foo() as f32; | ^^^^^^^^^^^^ help: try: `foo()` -error: aborting due to 31 previous errors +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 38 previous errors +======= +error: aborting due to 33 previous errors +>>>>>>> 7f7979f80 (emit `unnecessary_cast` on raw pointers as well) +======= +error: aborting due to 37 previous errors +>>>>>>> d2de5769a (add generics in test) +======= +error: aborting due to 38 previous errors +>>>>>>> d7a98f507 (also ensure generics with the same type are linted) diff --git a/tests/ui/unnecessary_cast_unfixable.rs b/tests/ui/unnecessary_cast_unfixable.rs new file mode 100644 index 000000000000..0e027f6042e6 --- /dev/null +++ b/tests/ui/unnecessary_cast_unfixable.rs @@ -0,0 +1,22 @@ +#![warn(clippy::unnecessary_cast)] + +fn main() { + let _ = std::ptr::null() as *const u8; +} + +mod issue11113 { + #[repr(C)] + struct Vtbl { + query: unsafe extern "system" fn(), + } + + struct TearOff { + object: *mut std::ffi::c_void, + } + + impl TearOff { + unsafe fn query(&self) { + ((*(*(self.object as *mut *mut _) as *mut Vtbl)).query)() + } + } +} diff --git a/tests/ui/unnecessary_cast_unfixable.stderr b/tests/ui/unnecessary_cast_unfixable.stderr new file mode 100644 index 000000000000..eecf245686a8 --- /dev/null +++ b/tests/ui/unnecessary_cast_unfixable.stderr @@ -0,0 +1,16 @@ +error: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`) + --> $DIR/unnecessary_cast_unfixable.rs:4:13 + | +LL | let _ = std::ptr::null() as *const u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::null()` + | + = note: `-D clippy::unnecessary-cast` implied by `-D warnings` + +error: casting raw pointers to the same type and constness is unnecessary (`*mut issue11113::Vtbl` -> `*mut issue11113::Vtbl`) + --> $DIR/unnecessary_cast_unfixable.rs:19:16 + | +LL | ((*(*(self.object as *mut *mut _) as *mut Vtbl)).query)() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `*(self.object as *mut *mut _)` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/unnecessary_clone.rs b/tests/ui/unnecessary_clone.rs index 8b1629b19a76..7ceed3c75fd8 100644 --- a/tests/ui/unnecessary_clone.rs +++ b/tests/ui/unnecessary_clone.rs @@ -42,14 +42,6 @@ fn clone_on_copy_generic(t: T) { Some(t).clone(); } -fn clone_on_double_ref() { - let x = vec![1]; - let y = &&x; - let z: &Vec<_> = y.clone(); - - println!("{:p} {:p}", *y, z); -} - mod many_derefs { struct A; struct B; @@ -84,11 +76,6 @@ mod many_derefs { let _: E = a.clone(); let _: E = *****a; } - - fn check(mut encoded: &[u8]) { - let _ = &mut encoded.clone(); - let _ = &encoded.clone(); - } } mod issue2076 { diff --git a/tests/ui/unnecessary_clone.stderr b/tests/ui/unnecessary_clone.stderr index 6022d9fa4c5c..23639f6d41a0 100644 --- a/tests/ui/unnecessary_clone.stderr +++ b/tests/ui/unnecessary_clone.stderr @@ -2,7 +2,7 @@ error: using `.clone()` on a ref-counted pointer --> $DIR/unnecessary_clone.rs:23:5 | LL | rc.clone(); - | ^^^^^^^^^^ help: try this: `Rc::::clone(&rc)` + | ^^^^^^^^^^ help: try: `Rc::::clone(&rc)` | = note: `-D clippy::clone-on-ref-ptr` implied by `-D warnings` @@ -10,25 +10,25 @@ error: using `.clone()` on a ref-counted pointer --> $DIR/unnecessary_clone.rs:26:5 | LL | arc.clone(); - | ^^^^^^^^^^^ help: try this: `Arc::::clone(&arc)` + | ^^^^^^^^^^^ help: try: `Arc::::clone(&arc)` error: using `.clone()` on a ref-counted pointer --> $DIR/unnecessary_clone.rs:29:5 | LL | rcweak.clone(); - | ^^^^^^^^^^^^^^ help: try this: `Weak::::clone(&rcweak)` + | ^^^^^^^^^^^^^^ help: try: `Weak::::clone(&rcweak)` error: using `.clone()` on a ref-counted pointer --> $DIR/unnecessary_clone.rs:32:5 | LL | arc_weak.clone(); - | ^^^^^^^^^^^^^^^^ help: try this: `Weak::::clone(&arc_weak)` + | ^^^^^^^^^^^^^^^^ help: try: `Weak::::clone(&arc_weak)` error: using `.clone()` on a ref-counted pointer --> $DIR/unnecessary_clone.rs:36:33 | LL | let _: Arc = x.clone(); - | ^^^^^^^^^ help: try this: `Arc::::clone(&x)` + | ^^^^^^^^^ help: try: `Arc::::clone(&x)` error: using `clone` on type `T` which implements the `Copy` trait --> $DIR/unnecessary_clone.rs:40:5 @@ -44,63 +44,17 @@ error: using `clone` on type `Option` which implements the `Copy` trait LL | Some(t).clone(); | ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)` -error: using `clone` on a double-reference; this will copy the reference of type `&Vec` instead of cloning the inner type - --> $DIR/unnecessary_clone.rs:48:22 - | -LL | let z: &Vec<_> = y.clone(); - | ^^^^^^^^^ - | - = note: `#[deny(clippy::clone_double_ref)]` on by default -help: try dereferencing it - | -LL | let z: &Vec<_> = &(*y).clone(); - | ~~~~~~~~~~~~~ -help: or try being explicit if you are sure, that you want to clone a reference - | -LL | let z: &Vec<_> = <&Vec>::clone(y); - | ~~~~~~~~~~~~~~~~~~~~~ - error: using `clone` on type `E` which implements the `Copy` trait - --> $DIR/unnecessary_clone.rs:84:20 + --> $DIR/unnecessary_clone.rs:76:20 | LL | let _: E = a.clone(); | ^^^^^^^^^ help: try dereferencing it: `*****a` -error: using `clone` on a double-reference; this will copy the reference of type `&[u8]` instead of cloning the inner type - --> $DIR/unnecessary_clone.rs:89:22 - | -LL | let _ = &mut encoded.clone(); - | ^^^^^^^^^^^^^^^ - | -help: try dereferencing it - | -LL | let _ = &mut &(*encoded).clone(); - | ~~~~~~~~~~~~~~~~~~~ -help: or try being explicit if you are sure, that you want to clone a reference - | -LL | let _ = &mut <&[u8]>::clone(encoded); - | ~~~~~~~~~~~~~~~~~~~~~~~ - -error: using `clone` on a double-reference; this will copy the reference of type `&[u8]` instead of cloning the inner type - --> $DIR/unnecessary_clone.rs:90:18 - | -LL | let _ = &encoded.clone(); - | ^^^^^^^^^^^^^^^ - | -help: try dereferencing it - | -LL | let _ = &&(*encoded).clone(); - | ~~~~~~~~~~~~~~~~~~~ -help: or try being explicit if you are sure, that you want to clone a reference - | -LL | let _ = &<&[u8]>::clone(encoded); - | ~~~~~~~~~~~~~~~~~~~~~~~ - error: using `.clone()` on a ref-counted pointer - --> $DIR/unnecessary_clone.rs:108:14 + --> $DIR/unnecessary_clone.rs:95:14 | LL | Some(try_opt!(Some(rc)).clone()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Rc::::clone(&try_opt!(Some(rc)))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Rc::::clone(&try_opt!(Some(rc)))` -error: aborting due to 12 previous errors +error: aborting due to 9 previous errors diff --git a/tests/ui/unnecessary_fold.fixed b/tests/ui/unnecessary_fold.fixed index 52300a3b6406..bd1d4a152aeb 100644 --- a/tests/ui/unnecessary_fold.fixed +++ b/tests/ui/unnecessary_fold.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] @@ -49,4 +49,28 @@ fn unnecessary_fold_over_multiple_lines() { .any(|x| x > 2); } +fn issue10000() { + use std::collections::HashMap; + use std::hash::BuildHasher; + + fn anything(_: T) {} + fn num(_: i32) {} + fn smoketest_map(mut map: HashMap) { + map.insert(0, 0); + assert_eq!(map.values().sum::(), 0); + + // more cases: + let _ = map.values().sum::(); + let _ = map.values().product::(); + let _: i32 = map.values().sum(); + let _: i32 = map.values().product(); + anything(map.values().sum::()); + anything(map.values().product::()); + num(map.values().sum()); + num(map.values().product()); + } + + smoketest_map(HashMap::new()); +} + fn main() {} diff --git a/tests/ui/unnecessary_fold.rs b/tests/ui/unnecessary_fold.rs index 4028d80c0a3c..d27cc460c44a 100644 --- a/tests/ui/unnecessary_fold.rs +++ b/tests/ui/unnecessary_fold.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] @@ -49,4 +49,28 @@ fn unnecessary_fold_over_multiple_lines() { .fold(false, |acc, x| acc || x > 2); } +fn issue10000() { + use std::collections::HashMap; + use std::hash::BuildHasher; + + fn anything(_: T) {} + fn num(_: i32) {} + fn smoketest_map(mut map: HashMap) { + map.insert(0, 0); + assert_eq!(map.values().fold(0, |x, y| x + y), 0); + + // more cases: + let _ = map.values().fold(0, |x, y| x + y); + let _ = map.values().fold(1, |x, y| x * y); + let _: i32 = map.values().fold(0, |x, y| x + y); + let _: i32 = map.values().fold(1, |x, y| x * y); + anything(map.values().fold(0, |x, y| x + y)); + anything(map.values().fold(1, |x, y| x * y)); + num(map.values().fold(0, |x, y| x + y)); + num(map.values().fold(1, |x, y| x * y)); + } + + smoketest_map(HashMap::new()); +} + fn main() {} diff --git a/tests/ui/unnecessary_fold.stderr b/tests/ui/unnecessary_fold.stderr index 22c44588ab7a..98979f7477fb 100644 --- a/tests/ui/unnecessary_fold.stderr +++ b/tests/ui/unnecessary_fold.stderr @@ -36,5 +36,59 @@ error: this `.fold` can be written more succinctly using another method LL | .fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` -error: aborting due to 6 previous errors +error: this `.fold` can be written more succinctly using another method + --> $DIR/unnecessary_fold.rs:60:33 + | +LL | assert_eq!(map.values().fold(0, |x, y| x + y), 0); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` + +error: this `.fold` can be written more succinctly using another method + --> $DIR/unnecessary_fold.rs:63:30 + | +LL | let _ = map.values().fold(0, |x, y| x + y); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` + +error: this `.fold` can be written more succinctly using another method + --> $DIR/unnecessary_fold.rs:64:30 + | +LL | let _ = map.values().fold(1, |x, y| x * y); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` + +error: this `.fold` can be written more succinctly using another method + --> $DIR/unnecessary_fold.rs:65:35 + | +LL | let _: i32 = map.values().fold(0, |x, y| x + y); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> $DIR/unnecessary_fold.rs:66:35 + | +LL | let _: i32 = map.values().fold(1, |x, y| x * y); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: this `.fold` can be written more succinctly using another method + --> $DIR/unnecessary_fold.rs:67:31 + | +LL | anything(map.values().fold(0, |x, y| x + y)); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` + +error: this `.fold` can be written more succinctly using another method + --> $DIR/unnecessary_fold.rs:68:31 + | +LL | anything(map.values().fold(1, |x, y| x * y)); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` + +error: this `.fold` can be written more succinctly using another method + --> $DIR/unnecessary_fold.rs:69:26 + | +LL | num(map.values().fold(0, |x, y| x + y)); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> $DIR/unnecessary_fold.rs:70:26 + | +LL | num(map.values().fold(1, |x, y| x * y)); + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: aborting due to 15 previous errors diff --git a/tests/ui/unnecessary_iter_cloned.fixed b/tests/ui/unnecessary_iter_cloned.fixed index e01e9f07bafd..a0f8dd1a200d 100644 --- a/tests/ui/unnecessary_iter_cloned.fixed +++ b/tests/ui/unnecessary_iter_cloned.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_assignments)] #![warn(clippy::unnecessary_to_owned)] diff --git a/tests/ui/unnecessary_iter_cloned.rs b/tests/ui/unnecessary_iter_cloned.rs index 6ef2966c8b76..98f2dfe75491 100644 --- a/tests/ui/unnecessary_iter_cloned.rs +++ b/tests/ui/unnecessary_iter_cloned.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_assignments)] #![warn(clippy::unnecessary_to_owned)] diff --git a/tests/ui/unnecessary_join.fixed b/tests/ui/unnecessary_join.fixed index 347953960257..f13a5275e31b 100644 --- a/tests/ui/unnecessary_join.fixed +++ b/tests/ui/unnecessary_join.fixed @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_join)] -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::uninlined_format_args, clippy::useless_vec)] fn main() { // should be linted diff --git a/tests/ui/unnecessary_join.rs b/tests/ui/unnecessary_join.rs index 344918cd2a2e..6014d723a2f4 100644 --- a/tests/ui/unnecessary_join.rs +++ b/tests/ui/unnecessary_join.rs @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_join)] -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::uninlined_format_args, clippy::useless_vec)] fn main() { // should be linted diff --git a/tests/ui/unnecessary_lazy_eval.fixed b/tests/ui/unnecessary_lazy_eval.fixed index 3b93800f8b75..5d954211043f 100644 --- a/tests/ui/unnecessary_lazy_eval.fixed +++ b/tests/ui/unnecessary_lazy_eval.fixed @@ -1,9 +1,26 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::unnecessary_lazy_evaluations)] #![allow(clippy::redundant_closure)] #![allow(clippy::bind_instead_of_map)] #![allow(clippy::map_identity)] +#![allow(clippy::needless_borrow)] +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::unnecessary_literal_unwrap)] + +use std::ops::Deref; +======= +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= +#![allow(clippy::unnecessary_literal_unwrap)] +>>>>>>> bfd5abad4 (Fix all the other tests) + +use std::ops::Deref; extern crate proc_macros; use proc_macros::with_span; @@ -41,6 +58,15 @@ impl Drop for Issue9427FollowUp { } } +struct Issue10437; +impl Deref for Issue10437 { + type Target = u32; + fn deref(&self) -> &Self::Target { + println!("side effect deref"); + &0 + } +} + fn main() { let astronomers_pi = 10; let ext_arr: [usize; 1] = [2]; @@ -65,6 +91,24 @@ fn main() { let _ = nested_tuple_opt.unwrap_or(Some((1, 2))); let _ = cond.then_some(astronomers_pi); + // Should lint - Builtin deref + let r = &1; + let _ = Some(1).unwrap_or(*r); + let b = Box::new(1); + let _ = Some(1).unwrap_or(*b); +<<<<<<< HEAD +<<<<<<< HEAD + // Should lint - Builtin deref through autoderef + let _ = Some(1).as_ref().unwrap_or(&r); + let _ = Some(1).as_ref().unwrap_or(&b); +======= +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + // Should lint - Builtin deref through autoderef + let _ = Some(1).as_ref().unwrap_or(&r); + let _ = Some(1).as_ref().unwrap_or(&b); +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) + // Cases when unwrap is not called on a simple variable let _ = Some(10).unwrap_or(2); let _ = Some(10).and(ext_opt); @@ -93,6 +137,21 @@ fn main() { let _ = deep.0.or_else(|| some_call()); let _ = opt.ok_or_else(|| ext_arr[0]); + let _ = Some(1).unwrap_or_else(|| *Issue10437); // Issue10437 has a deref impl + let _ = Some(1).unwrap_or(*Issue10437); + +<<<<<<< HEAD +<<<<<<< HEAD + let _ = Some(1).as_ref().unwrap_or_else(|| &Issue10437); + let _ = Some(1).as_ref().unwrap_or(&Issue10437); + +======= +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + let _ = Some(1).as_ref().unwrap_or_else(|| &Issue10437); + let _ = Some(1).as_ref().unwrap_or(&Issue10437); + +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) // Should not lint - bool let _ = (0 == 1).then(|| Issue9427(0)); // Issue9427 has a significant drop let _ = false.then(|| Issue9427FollowUp); // Issue9427FollowUp has a significant drop diff --git a/tests/ui/unnecessary_lazy_eval.rs b/tests/ui/unnecessary_lazy_eval.rs index 2851c0c51904..a6a51fe852a1 100644 --- a/tests/ui/unnecessary_lazy_eval.rs +++ b/tests/ui/unnecessary_lazy_eval.rs @@ -1,9 +1,26 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build: proc_macros.rs:proc-macro +======= +//@aux-build: proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::unnecessary_lazy_evaluations)] #![allow(clippy::redundant_closure)] #![allow(clippy::bind_instead_of_map)] #![allow(clippy::map_identity)] +#![allow(clippy::needless_borrow)] +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::unnecessary_literal_unwrap)] + +use std::ops::Deref; +======= +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= +#![allow(clippy::unnecessary_literal_unwrap)] +>>>>>>> bfd5abad4 (Fix all the other tests) + +use std::ops::Deref; extern crate proc_macros; use proc_macros::with_span; @@ -41,6 +58,15 @@ impl Drop for Issue9427FollowUp { } } +struct Issue10437; +impl Deref for Issue10437 { + type Target = u32; + fn deref(&self) -> &Self::Target { + println!("side effect deref"); + &0 + } +} + fn main() { let astronomers_pi = 10; let ext_arr: [usize; 1] = [2]; @@ -65,6 +91,24 @@ fn main() { let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); let _ = cond.then(|| astronomers_pi); + // Should lint - Builtin deref + let r = &1; + let _ = Some(1).unwrap_or_else(|| *r); + let b = Box::new(1); + let _ = Some(1).unwrap_or_else(|| *b); +<<<<<<< HEAD +<<<<<<< HEAD + // Should lint - Builtin deref through autoderef + let _ = Some(1).as_ref().unwrap_or_else(|| &r); + let _ = Some(1).as_ref().unwrap_or_else(|| &b); +======= +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + // Should lint - Builtin deref through autoderef + let _ = Some(1).as_ref().unwrap_or_else(|| &r); + let _ = Some(1).as_ref().unwrap_or_else(|| &b); +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) + // Cases when unwrap is not called on a simple variable let _ = Some(10).unwrap_or_else(|| 2); let _ = Some(10).and_then(|_| ext_opt); @@ -93,6 +137,21 @@ fn main() { let _ = deep.0.or_else(|| some_call()); let _ = opt.ok_or_else(|| ext_arr[0]); + let _ = Some(1).unwrap_or_else(|| *Issue10437); // Issue10437 has a deref impl + let _ = Some(1).unwrap_or(*Issue10437); + +<<<<<<< HEAD +<<<<<<< HEAD + let _ = Some(1).as_ref().unwrap_or_else(|| &Issue10437); + let _ = Some(1).as_ref().unwrap_or(&Issue10437); + +======= +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + let _ = Some(1).as_ref().unwrap_or_else(|| &Issue10437); + let _ = Some(1).as_ref().unwrap_or(&Issue10437); + +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) // Should not lint - bool let _ = (0 == 1).then(|| Issue9427(0)); // Issue9427 has a significant drop let _ = false.then(|| Issue9427FollowUp); // Issue9427FollowUp has a significant drop diff --git a/tests/ui/unnecessary_lazy_eval.stderr b/tests/ui/unnecessary_lazy_eval.stderr index 0339755442c5..f55656d3d7d2 100644 --- a/tests/ui/unnecessary_lazy_eval.stderr +++ b/tests/ui/unnecessary_lazy_eval.stderr @@ -1,5 +1,17 @@ error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:56:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:69:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:67:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:68:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:69:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = opt.unwrap_or_else(|| 2); | ^^^^-------------------- @@ -9,7 +21,19 @@ LL | let _ = opt.unwrap_or_else(|| 2); = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:57:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:70:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:68:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:69:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:70:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = opt.unwrap_or_else(|| astronomers_pi); | ^^^^--------------------------------- @@ -17,7 +41,19 @@ LL | let _ = opt.unwrap_or_else(|| astronomers_pi); | help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:58:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:71:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:69:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:70:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:71:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = opt.unwrap_or_else(|| ext_str.some_field); | ^^^^------------------------------------- @@ -25,7 +61,19 @@ LL | let _ = opt.unwrap_or_else(|| ext_str.some_field); | help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:60:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:73:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:71:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:72:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:73:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = opt.and_then(|_| ext_opt); | ^^^^--------------------- @@ -33,7 +81,19 @@ LL | let _ = opt.and_then(|_| ext_opt); | help: use `and(..)` instead: `and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:61:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:74:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:72:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:73:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:74:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = opt.or_else(|| ext_opt); | ^^^^------------------- @@ -41,7 +101,19 @@ LL | let _ = opt.or_else(|| ext_opt); | help: use `or(..)` instead: `or(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:62:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:75:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:73:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:74:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:75:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = opt.or_else(|| None); | ^^^^---------------- @@ -49,7 +121,19 @@ LL | let _ = opt.or_else(|| None); | help: use `or(..)` instead: `or(None)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:63:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:76:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:74:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:75:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:76:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = opt.get_or_insert_with(|| 2); | ^^^^------------------------ @@ -57,7 +141,19 @@ LL | let _ = opt.get_or_insert_with(|| 2); | help: use `get_or_insert(..)` instead: `get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:64:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:77:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:75:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:76:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:77:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = opt.ok_or_else(|| 2); | ^^^^---------------- @@ -65,7 +161,19 @@ LL | let _ = opt.ok_or_else(|| 2); | help: use `ok_or(..)` instead: `ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:65:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:78:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:76:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:77:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:78:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); | ^^^^^^^^^^^^^^^^^------------------------------- @@ -73,7 +181,19 @@ LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); | help: use `unwrap_or(..)` instead: `unwrap_or(Some((1, 2)))` error: unnecessary closure used with `bool::then` - --> $DIR/unnecessary_lazy_eval.rs:66:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:79:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:77:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:78:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:79:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = cond.then(|| astronomers_pi); | ^^^^^----------------------- @@ -81,7 +201,87 @@ LL | let _ = cond.then(|| astronomers_pi); | help: use `then_some(..)` instead: `then_some(astronomers_pi)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:69:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:83:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:81:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:82:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:83:13 +>>>>>>> bfd5abad4 (Fix all the other tests) + | +LL | let _ = Some(1).unwrap_or_else(|| *r); + | ^^^^^^^^--------------------- + | | + | help: use `unwrap_or(..)` instead: `unwrap_or(*r)` + +error: unnecessary closure used to substitute value for `Option::None` +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:85:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:83:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:84:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:85:13 +>>>>>>> bfd5abad4 (Fix all the other tests) + | +LL | let _ = Some(1).unwrap_or_else(|| *b); + | ^^^^^^^^--------------------- + | | + | help: use `unwrap_or(..)` instead: `unwrap_or(*b)` + +error: unnecessary closure used to substitute value for `Option::None` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:87:13 + | +LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r); + | ^^^^^^^^^^^^^^^^^--------------------- + | | + | help: use `unwrap_or(..)` instead: `unwrap_or(&r)` + +error: unnecessary closure used to substitute value for `Option::None` + --> $DIR/unnecessary_lazy_eval.rs:88:13 + | +LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b); + | ^^^^^^^^^^^^^^^^^--------------------- + | | + | help: use `unwrap_or(..)` instead: `unwrap_or(&b)` + +error: unnecessary closure used to substitute value for `Option::None` + --> $DIR/unnecessary_lazy_eval.rs:91:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:86:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:87:13 +>>>>>>> bfd5abad4 (Fix all the other tests) + | +LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r); + | ^^^^^^^^^^^^^^^^^--------------------- + | | + | help: use `unwrap_or(..)` instead: `unwrap_or(&r)` + +error: unnecessary closure used to substitute value for `Option::None` + --> $DIR/unnecessary_lazy_eval.rs:88:13 + | +LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b); + | ^^^^^^^^^^^^^^^^^--------------------- + | | + | help: use `unwrap_or(..)` instead: `unwrap_or(&b)` + +error: unnecessary closure used to substitute value for `Option::None` + --> $DIR/unnecessary_lazy_eval.rs:91:13 | LL | let _ = Some(10).unwrap_or_else(|| 2); | ^^^^^^^^^-------------------- @@ -89,7 +289,19 @@ LL | let _ = Some(10).unwrap_or_else(|| 2); | help: use `unwrap_or(..)` instead: `unwrap_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:70:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:92:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:87:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:91:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:92:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = Some(10).and_then(|_| ext_opt); | ^^^^^^^^^--------------------- @@ -97,7 +309,19 @@ LL | let _ = Some(10).and_then(|_| ext_opt); | help: use `and(..)` instead: `and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:71:28 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:93:28 +======= + --> $DIR/unnecessary_lazy_eval.rs:88:28 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:92:28 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:93:28 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _: Option = None.or_else(|| ext_opt); | ^^^^^------------------- @@ -105,7 +329,19 @@ LL | let _: Option = None.or_else(|| ext_opt); | help: use `or(..)` instead: `or(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:72:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:94:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:89:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:93:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:94:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = None.get_or_insert_with(|| 2); | ^^^^^------------------------ @@ -113,7 +349,19 @@ LL | let _ = None.get_or_insert_with(|| 2); | help: use `get_or_insert(..)` instead: `get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:73:35 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:95:35 +======= + --> $DIR/unnecessary_lazy_eval.rs:90:35 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:94:35 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:95:35 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _: Result = None.ok_or_else(|| 2); | ^^^^^---------------- @@ -121,7 +369,19 @@ LL | let _: Result = None.ok_or_else(|| 2); | help: use `ok_or(..)` instead: `ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:74:28 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:96:28 +======= + --> $DIR/unnecessary_lazy_eval.rs:91:28 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:95:28 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:96:28 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _: Option = None.or_else(|| None); | ^^^^^---------------- @@ -129,7 +389,19 @@ LL | let _: Option = None.or_else(|| None); | help: use `or(..)` instead: `or(None)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:77:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:99:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:94:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:98:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:99:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = deep.0.unwrap_or_else(|| 2); | ^^^^^^^-------------------- @@ -137,7 +409,19 @@ LL | let _ = deep.0.unwrap_or_else(|| 2); | help: use `unwrap_or(..)` instead: `unwrap_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:78:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:100:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:95:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:99:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:100:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = deep.0.and_then(|_| ext_opt); | ^^^^^^^--------------------- @@ -145,7 +429,19 @@ LL | let _ = deep.0.and_then(|_| ext_opt); | help: use `and(..)` instead: `and(ext_opt)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:79:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:101:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:96:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:100:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:101:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = deep.0.or_else(|| None); | ^^^^^^^---------------- @@ -153,7 +449,19 @@ LL | let _ = deep.0.or_else(|| None); | help: use `or(..)` instead: `or(None)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:80:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:102:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:97:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:101:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:102:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = deep.0.get_or_insert_with(|| 2); | ^^^^^^^------------------------ @@ -161,7 +469,19 @@ LL | let _ = deep.0.get_or_insert_with(|| 2); | help: use `get_or_insert(..)` instead: `get_or_insert(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:81:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:103:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:98:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:102:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:103:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = deep.0.ok_or_else(|| 2); | ^^^^^^^---------------- @@ -169,7 +489,19 @@ LL | let _ = deep.0.ok_or_else(|| 2); | help: use `ok_or(..)` instead: `ok_or(2)` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:105:28 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:133:28 +======= + --> $DIR/unnecessary_lazy_eval.rs:125:28 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:132:28 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:133:28 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _: Option = None.or_else(|| Some(3)); | ^^^^^------------------- @@ -177,7 +509,19 @@ LL | let _: Option = None.or_else(|| Some(3)); | help: use `or(..)` instead: `or(Some(3))` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:106:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:134:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:126:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:133:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:134:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = deep.0.or_else(|| Some(3)); | ^^^^^^^------------------- @@ -185,7 +529,19 @@ LL | let _ = deep.0.or_else(|| Some(3)); | help: use `or(..)` instead: `or(Some(3))` error: unnecessary closure used to substitute value for `Option::None` - --> $DIR/unnecessary_lazy_eval.rs:107:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:135:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:127:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:134:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:135:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = opt.or_else(|| Some(3)); | ^^^^------------------- @@ -193,7 +549,19 @@ LL | let _ = opt.or_else(|| Some(3)); | help: use `or(..)` instead: `or(Some(3))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:113:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:141:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:133:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:140:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:141:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = res2.unwrap_or_else(|_| 2); | ^^^^^--------------------- @@ -201,7 +569,19 @@ LL | let _ = res2.unwrap_or_else(|_| 2); | help: use `unwrap_or(..)` instead: `unwrap_or(2)` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:114:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:142:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:134:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:141:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:142:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = res2.unwrap_or_else(|_| astronomers_pi); | ^^^^^---------------------------------- @@ -209,7 +589,19 @@ LL | let _ = res2.unwrap_or_else(|_| astronomers_pi); | help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:115:13 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:143:13 +======= + --> $DIR/unnecessary_lazy_eval.rs:135:13 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:142:13 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:143:13 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field); | ^^^^^-------------------------------------- @@ -217,7 +609,19 @@ LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field); | help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:137:35 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:165:35 +======= + --> $DIR/unnecessary_lazy_eval.rs:157:35 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:164:35 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:165:35 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _: Result = res.and_then(|_| Err(2)); | ^^^^-------------------- @@ -225,7 +629,19 @@ LL | let _: Result = res.and_then(|_| Err(2)); | help: use `and(..)` instead: `and(Err(2))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:138:35 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:166:35 +======= + --> $DIR/unnecessary_lazy_eval.rs:158:35 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:165:35 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:166:35 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _: Result = res.and_then(|_| Err(astronomers_pi)); | ^^^^--------------------------------- @@ -233,7 +649,19 @@ LL | let _: Result = res.and_then(|_| Err(astronomers_pi)); | help: use `and(..)` instead: `and(Err(astronomers_pi))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:139:35 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:167:35 +======= + --> $DIR/unnecessary_lazy_eval.rs:159:35 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:166:35 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:167:35 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _: Result = res.and_then(|_| Err(ext_str.some_field)); | ^^^^------------------------------------- @@ -241,7 +669,19 @@ LL | let _: Result = res.and_then(|_| Err(ext_str.some_field)) | help: use `and(..)` instead: `and(Err(ext_str.some_field))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:141:35 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:169:35 +======= + --> $DIR/unnecessary_lazy_eval.rs:161:35 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:168:35 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:169:35 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _: Result = res.or_else(|_| Ok(2)); | ^^^^------------------ @@ -249,7 +689,19 @@ LL | let _: Result = res.or_else(|_| Ok(2)); | help: use `or(..)` instead: `or(Ok(2))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:142:35 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:170:35 +======= + --> $DIR/unnecessary_lazy_eval.rs:162:35 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:169:35 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:170:35 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _: Result = res.or_else(|_| Ok(astronomers_pi)); | ^^^^------------------------------- @@ -257,7 +709,19 @@ LL | let _: Result = res.or_else(|_| Ok(astronomers_pi)); | help: use `or(..)` instead: `or(Ok(astronomers_pi))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:143:35 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:171:35 +======= + --> $DIR/unnecessary_lazy_eval.rs:163:35 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:170:35 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:171:35 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _: Result = res.or_else(|_| Ok(ext_str.some_field)); | ^^^^----------------------------------- @@ -265,7 +729,19 @@ LL | let _: Result = res.or_else(|_| Ok(ext_str.some_field)); | help: use `or(..)` instead: `or(Ok(ext_str.some_field))` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval.rs:144:35 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_lazy_eval.rs:172:35 +======= + --> $DIR/unnecessary_lazy_eval.rs:164:35 +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= + --> $DIR/unnecessary_lazy_eval.rs:171:35 +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) +======= + --> $DIR/unnecessary_lazy_eval.rs:172:35 +>>>>>>> bfd5abad4 (Fix all the other tests) | LL | let _: Result = res. | ___________________________________^ @@ -279,5 +755,13 @@ LL | | or_else(|_| Ok(ext_str.some_field)); | | | help: use `or(..)` instead: `or(Ok(ext_str.some_field))` -error: aborting due to 34 previous errors +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 38 previous errors +======= +error: aborting due to 36 previous errors +>>>>>>> a239c8b52 ([`unnecessary_lazy_eval`]: don't lint on types with deref impl) +======= +error: aborting due to 38 previous errors +>>>>>>> e70dd55fd (account for autoderef in eager_or_lazy) diff --git a/tests/ui/unnecessary_lazy_eval_unfixable.rs b/tests/ui/unnecessary_lazy_eval_unfixable.rs index b05dd143bfd7..b4a1f81679ad 100644 --- a/tests/ui/unnecessary_lazy_eval_unfixable.rs +++ b/tests/ui/unnecessary_lazy_eval_unfixable.rs @@ -1,4 +1,5 @@ #![warn(clippy::unnecessary_lazy_evaluations)] +#![allow(clippy::unnecessary_literal_unwrap)] struct Deep(Option); diff --git a/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/tests/ui/unnecessary_lazy_eval_unfixable.stderr index 20acab6e844f..7f353ba06982 100644 --- a/tests/ui/unnecessary_lazy_eval_unfixable.stderr +++ b/tests/ui/unnecessary_lazy_eval_unfixable.stderr @@ -1,5 +1,5 @@ error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval_unfixable.rs:12:13 + --> $DIR/unnecessary_lazy_eval_unfixable.rs:13:13 | LL | let _ = Ok(1).unwrap_or_else(|()| 2); | ^^^^^^---------------------- @@ -9,7 +9,7 @@ LL | let _ = Ok(1).unwrap_or_else(|()| 2); = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval_unfixable.rs:16:13 + --> $DIR/unnecessary_lazy_eval_unfixable.rs:17:13 | LL | let _ = Ok(1).unwrap_or_else(|e::E| 2); | ^^^^^^------------------------ @@ -17,7 +17,7 @@ LL | let _ = Ok(1).unwrap_or_else(|e::E| 2); | help: use `unwrap_or(..)` instead: `unwrap_or(2)` error: unnecessary closure used to substitute value for `Result::Err` - --> $DIR/unnecessary_lazy_eval_unfixable.rs:17:13 + --> $DIR/unnecessary_lazy_eval_unfixable.rs:18:13 | LL | let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); | ^^^^^^------------------------------------- diff --git a/tests/ui/unnecessary_literal_unwrap.fixed b/tests/ui/unnecessary_literal_unwrap.fixed new file mode 100644 index 000000000000..1ca312113ffa --- /dev/null +++ b/tests/ui/unnecessary_literal_unwrap.fixed @@ -0,0 +1,198 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +#![warn(clippy::unnecessary_literal_unwrap)] +#![allow(unreachable_code)] +#![allow( + clippy::unnecessary_lazy_evaluations, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect +)] +<<<<<<< HEAD + +fn unwrap_option_some() { + let _val = 1; + let _val = 1; + + 1; + 1; +} + +fn unwrap_option_none() { + let _val = panic!(); + let _val = panic!("this always happens"); + + panic!(); + panic!("this always happens"); +} + +fn unwrap_result_ok() { + let _val = 1; + let _val = 1; + let _val = panic!("{:?}", 1); + let _val = panic!("{1}: {:?}", 1, "this always happens"); + + 1; + 1; + panic!("{:?}", 1); + panic!("{1}: {:?}", 1, "this always happens"); +} + +fn unwrap_result_err() { + let _val = 1; + let _val = 1; + let _val = panic!("{:?}", 1); + let _val = panic!("{1}: {:?}", 1, "this always happens"); + + 1; + 1; + panic!("{:?}", 1); + panic!("{1}: {:?}", 1, "this always happens"); +} + +fn unwrap_methods_option() { + let _val = 1; + let _val = 1; + let _val = 1; + + 1; + 1; + 1; +} + +fn unwrap_methods_result() { + let _val = 1; + let _val = 1; + let _val = 1; + + 1; + 1; + 1; +} + +fn unwrap_from_binding() { + macro_rules! from_macro { + () => { + Some("") + }; + } + let val = from_macro!(); + let _ = val.unwrap_or(""); +} + +fn unwrap_unchecked() { + let _ = 1; + let _ = unsafe { 1 + *(&1 as *const i32) }; // needs to keep the unsafe block + let _ = 1 + 1; + let _ = 1; + let _ = unsafe { 1 + *(&1 as *const i32) }; + let _ = 1 + 1; + let _ = 123; +} + +fn main() { + unwrap_option_some(); + unwrap_option_none(); + unwrap_result_ok(); + unwrap_result_err(); + unwrap_methods_option(); + unwrap_methods_result(); +<<<<<<< HEAD +======= +//run-rustfix +======= +//@run-rustfix +>>>>>>> 6cf138e9b (Add more tests) +#![warn(clippy::unnecessary_literal_unwrap)] +#![allow(unreachable_code)] +#![allow(clippy::unnecessary_lazy_evaluations)] +======= +>>>>>>> 6e4c5561b (Preserve type annotations when present) + +fn unwrap_option_some() { + let _val = 1; + let _val = 1; + + 1; + 1; +} + +fn unwrap_option_none() { + let _val = panic!(); + let _val = panic!("this always happens"); + + panic!(); + panic!("this always happens"); +} + +fn unwrap_result_ok() { + let _val = 1; + let _val = 1; + let _val = panic!("{:?}", 1); + let _val = panic!("{1}: {:?}", 1, "this always happens"); + + 1; + 1; + panic!("{:?}", 1); + panic!("{1}: {:?}", 1, "this always happens"); +} + +fn unwrap_result_err() { + let _val = 1; + let _val = 1; + let _val = panic!("{:?}", 1); + let _val = panic!("{1}: {:?}", 1, "this always happens"); + + 1; + 1; + panic!("{:?}", 1); + panic!("{1}: {:?}", 1, "this always happens"); +} + +fn unwrap_methods_option() { + let _val = 1; + let _val = 1; + let _val = 1; + + 1; + 1; + 1; +} + +fn unwrap_methods_result() { + let _val = 1; + let _val = 1; + let _val = 1; + + 1; + 1; + 1; +} + +fn main() { +<<<<<<< HEAD + unwrap_option(); +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> daf619748 (Implement the suggestion) +======= + unwrap_result(); +<<<<<<< HEAD +>>>>>>> 1d159e7d1 (Recognize `Ok`) +======= +======= +======= + unwrap_option_some(); + unwrap_option_none(); +>>>>>>> 6e4dc93e2 (Support suggesting panics) + unwrap_result_ok(); + unwrap_result_err(); +>>>>>>> 69af0e13b (Recognize `Err`) + unwrap_methods_option(); + unwrap_methods_result(); +>>>>>>> 8f8350298 (Recognize `unwrap_or` methods) +======= + unwrap_unchecked(); +>>>>>>> cd1c8532e ([`unnecessary_literal_unwrap`]: lint `unwrap_unchecked`) +} diff --git a/tests/ui/unnecessary_literal_unwrap.rs b/tests/ui/unnecessary_literal_unwrap.rs new file mode 100644 index 000000000000..30a3d41b44d2 --- /dev/null +++ b/tests/ui/unnecessary_literal_unwrap.rs @@ -0,0 +1,201 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +//@run-rustfix +#![warn(clippy::unnecessary_literal_unwrap)] +#![allow(unreachable_code)] +#![allow( + clippy::unnecessary_lazy_evaluations, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect +)] +<<<<<<< HEAD + +fn unwrap_option_some() { + let _val = Some(1).unwrap(); + let _val = Some(1).expect("this never happens"); + + Some(1).unwrap(); + Some(1).expect("this never happens"); +} + +fn unwrap_option_none() { + let _val = None::<()>.unwrap(); + let _val = None::<()>.expect("this always happens"); + + None::<()>.unwrap(); + None::<()>.expect("this always happens"); +} + +fn unwrap_result_ok() { + let _val = Ok::<_, ()>(1).unwrap(); + let _val = Ok::<_, ()>(1).expect("this never happens"); + let _val = Ok::<_, ()>(1).unwrap_err(); + let _val = Ok::<_, ()>(1).expect_err("this always happens"); + + Ok::<_, ()>(1).unwrap(); + Ok::<_, ()>(1).expect("this never happens"); + Ok::<_, ()>(1).unwrap_err(); + Ok::<_, ()>(1).expect_err("this always happens"); +} + +fn unwrap_result_err() { + let _val = Err::<(), _>(1).unwrap_err(); + let _val = Err::<(), _>(1).expect_err("this never happens"); + let _val = Err::<(), _>(1).unwrap(); + let _val = Err::<(), _>(1).expect("this always happens"); + + Err::<(), _>(1).unwrap_err(); + Err::<(), _>(1).expect_err("this never happens"); + Err::<(), _>(1).unwrap(); + Err::<(), _>(1).expect("this always happens"); +} + +fn unwrap_methods_option() { + let _val = Some(1).unwrap_or(2); + let _val = Some(1).unwrap_or_default(); + let _val = Some(1).unwrap_or_else(|| 2); + + Some(1).unwrap_or(2); + Some(1).unwrap_or_default(); + Some(1).unwrap_or_else(|| 2); +} + +fn unwrap_methods_result() { + let _val = Ok::<_, ()>(1).unwrap_or(2); + let _val = Ok::<_, ()>(1).unwrap_or_default(); + let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2); + + Ok::<_, ()>(1).unwrap_or(2); + Ok::<_, ()>(1).unwrap_or_default(); + Ok::<_, ()>(1).unwrap_or_else(|_| 2); +} + +fn unwrap_from_binding() { + macro_rules! from_macro { + () => { + Some("") + }; + } + let val = from_macro!(); + let _ = val.unwrap_or(""); +} + +fn unwrap_unchecked() { + let _ = unsafe { Some(1).unwrap_unchecked() }; + let _ = unsafe { Some(1).unwrap_unchecked() + *(&1 as *const i32) }; // needs to keep the unsafe block + let _ = unsafe { Some(1).unwrap_unchecked() } + 1; + let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() }; + let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() + *(&1 as *const i32) }; + let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() } + 1; + let _ = unsafe { Err::<(), i32>(123).unwrap_err_unchecked() }; +} + +fn main() { + unwrap_option_some(); + unwrap_option_none(); + unwrap_result_ok(); + unwrap_result_err(); + unwrap_methods_option(); + unwrap_methods_result(); +<<<<<<< HEAD +======= +======= +//run-rustfix +>>>>>>> daf619748 (Implement the suggestion) +======= +//@run-rustfix +>>>>>>> 6cf138e9b (Add more tests) +#![warn(clippy::unnecessary_literal_unwrap)] +#![allow(unreachable_code)] +#![allow(clippy::unnecessary_lazy_evaluations)] +======= +>>>>>>> 6e4c5561b (Preserve type annotations when present) + +fn unwrap_option_some() { + let _val = Some(1).unwrap(); + let _val = Some(1).expect("this never happens"); + + Some(1).unwrap(); + Some(1).expect("this never happens"); +} + +fn unwrap_option_none() { + let _val = None::<()>.unwrap(); + let _val = None::<()>.expect("this always happens"); + + None::<()>.unwrap(); + None::<()>.expect("this always happens"); +} + +fn unwrap_result_ok() { + let _val = Ok::<_, ()>(1).unwrap(); + let _val = Ok::<_, ()>(1).expect("this never happens"); + let _val = Ok::<_, ()>(1).unwrap_err(); + let _val = Ok::<_, ()>(1).expect_err("this always happens"); + + Ok::<_, ()>(1).unwrap(); + Ok::<_, ()>(1).expect("this never happens"); + Ok::<_, ()>(1).unwrap_err(); + Ok::<_, ()>(1).expect_err("this always happens"); +} + +fn unwrap_result_err() { + let _val = Err::<(), _>(1).unwrap_err(); + let _val = Err::<(), _>(1).expect_err("this never happens"); + let _val = Err::<(), _>(1).unwrap(); + let _val = Err::<(), _>(1).expect("this always happens"); + + Err::<(), _>(1).unwrap_err(); + Err::<(), _>(1).expect_err("this never happens"); + Err::<(), _>(1).unwrap(); + Err::<(), _>(1).expect("this always happens"); +} + +fn unwrap_methods_option() { + let _val = Some(1).unwrap_or(2); + let _val = Some(1).unwrap_or_default(); + let _val = Some(1).unwrap_or_else(|| 2); + + Some(1).unwrap_or(2); + Some(1).unwrap_or_default(); + Some(1).unwrap_or_else(|| 2); +} + +fn unwrap_methods_result() { + let _val = Ok::<_, ()>(1).unwrap_or(2); + let _val = Ok::<_, ()>(1).unwrap_or_default(); + let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2); + + Ok::<_, ()>(1).unwrap_or(2); + Ok::<_, ()>(1).unwrap_or_default(); + Ok::<_, ()>(1).unwrap_or_else(|_| 2); +} + +fn main() { +<<<<<<< HEAD + unwrap_option(); +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> e707447a8 (Boilerplate for the new lint) +======= + unwrap_result(); +<<<<<<< HEAD +>>>>>>> 1d159e7d1 (Recognize `Ok`) +======= +======= +======= + unwrap_option_some(); + unwrap_option_none(); +>>>>>>> 6e4dc93e2 (Support suggesting panics) + unwrap_result_ok(); + unwrap_result_err(); +>>>>>>> 69af0e13b (Recognize `Err`) + unwrap_methods_option(); + unwrap_methods_result(); +>>>>>>> 8f8350298 (Recognize `unwrap_or` methods) +======= + unwrap_unchecked(); +>>>>>>> cd1c8532e ([`unnecessary_literal_unwrap`]: lint `unwrap_unchecked`) +} diff --git a/tests/ui/unnecessary_literal_unwrap.stderr b/tests/ui/unnecessary_literal_unwrap.stderr new file mode 100644 index 000000000000..804bb470b9ac --- /dev/null +++ b/tests/ui/unnecessary_literal_unwrap.stderr @@ -0,0 +1,1004 @@ +error: used `unwrap()` on `Some` value +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_literal_unwrap.rs:12:16 +======= + --> $DIR/unnecessary_literal_unwrap.rs:6:16 +>>>>>>> 7ed7283e0 (Recognize `unwrap_or_else` method) +======= + --> $DIR/unnecessary_literal_unwrap.rs:7:16 +>>>>>>> 6e4dc93e2 (Support suggesting panics) +======= + --> $DIR/unnecessary_literal_unwrap.rs:12:16 +>>>>>>> 6e4c5561b (Preserve type annotations when present) + | +LL | let _val = Some(1).unwrap(); + | ^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::unnecessary-literal-unwrap` implied by `-D warnings` +help: remove the `Some` and `unwrap()` + | +LL - let _val = Some(1).unwrap(); +LL + let _val = 1; + | + +error: used `expect()` on `Some` value +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_literal_unwrap.rs:13:16 +======= + --> $DIR/unnecessary_literal_unwrap.rs:8:16 +>>>>>>> 6e4dc93e2 (Support suggesting panics) +======= + --> $DIR/unnecessary_literal_unwrap.rs:13:16 +>>>>>>> 6e4c5561b (Preserve type annotations when present) + | +LL | let _val = Some(1).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `expect()` + | +LL - let _val = Some(1).expect("this never happens"); +LL + let _val = 1; + | + +<<<<<<< HEAD +<<<<<<< HEAD +error: used `unwrap()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:15:5 + | +LL | Some(1).unwrap(); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap()` + | +LL - Some(1).unwrap(); +LL + 1; + | + +error: used `expect()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:16:5 + | +LL | Some(1).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `expect()` + | +LL - Some(1).expect("this never happens"); +LL + 1; + | + +error: used `unwrap()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:20:16 + | +LL | let _val = None::<()>.unwrap(); + | ^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap()`: `panic!()` + +error: used `expect()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:21:16 + | +LL | let _val = None::<()>.expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `expect()` + | +LL | let _val = panic!("this always happens"); + | ~~~~~~~ ~ + +error: used `unwrap()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:23:5 + | +LL | None::<()>.unwrap(); + | ^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap()`: `panic!()` + +error: used `expect()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:24:5 + | +LL | None::<()>.expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +======= +error: used `unwrap()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:12:5 +======= +error: used `unwrap()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:15:5 +>>>>>>> 6e4c5561b (Preserve type annotations when present) + | +LL | Some(1).unwrap(); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap()` + | +LL - Some(1).unwrap(); +LL + 1; + | + +error: used `expect()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:16:5 + | +LL | Some(1).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `expect()` + | +LL - Some(1).expect("this never happens"); +LL + 1; + | + +error: used `unwrap()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:20:16 + | +LL | let _val = None::<()>.unwrap(); + | ^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap()`: `panic!()` + +error: used `expect()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:21:16 + | +<<<<<<< HEAD +LL | None::.expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>>>>>>> 6e4dc93e2 (Support suggesting panics) +======= +LL | let _val = None::<()>.expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `expect()` + | +LL | let _val = panic!("this always happens"); + | ~~~~~~~ ~ + +error: used `unwrap()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:23:5 + | +LL | None::<()>.unwrap(); + | ^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap()`: `panic!()` + +error: used `expect()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:24:5 + | +LL | None::<()>.expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>>>>>>> 6e4c5561b (Preserve type annotations when present) + | +help: remove the `None` and `expect()` + | +LL | panic!("this always happens"); + | ~~~~~~~ ~ + +<<<<<<< HEAD +error: used `unwrap()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:28:16 + | +LL | let _val = Ok::<_, ()>(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap()` + | +LL - let _val = Ok::<_, ()>(1).unwrap(); +LL + let _val = 1; + | + +error: used `expect()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:29:16 + | +LL | let _val = Ok::<_, ()>(1).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect()` + | +LL - let _val = Ok::<_, ()>(1).expect("this never happens"); +LL + let _val = 1; + | + +error: used `unwrap_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:30:16 + | +LL | let _val = Ok::<_, ()>(1).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_err()` + | +LL | let _val = panic!("{:?}", 1); + | ~~~~~~~~~~~~~~ ~ + +error: used `expect_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:31:16 + | +LL | let _val = Ok::<_, ()>(1).expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect_err()` + | +LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); + | ~~~~~~~~~~~~~~~~~~~ ~ + +error: used `unwrap()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:33:5 + | +LL | Ok::<_, ()>(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap()` + | +LL - Ok::<_, ()>(1).unwrap(); +LL + 1; + | + +error: used `expect()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:34:5 + | +LL | Ok::<_, ()>(1).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect()` + | +LL - Ok::<_, ()>(1).expect("this never happens"); +LL + 1; + | + +error: used `unwrap_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:35:5 + | +LL | Ok::<_, ()>(1).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_err()` + | +LL | panic!("{:?}", 1); + | ~~~~~~~~~~~~~~ ~ + +error: used `expect_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:36:5 + | +LL | Ok::<_, ()>(1).expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect_err()` + | +LL | panic!("{1}: {:?}", 1, "this always happens"); + | ~~~~~~~~~~~~~~~~~~~ ~ + +error: used `unwrap_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:40:16 + | +LL | let _val = Err::<(), _>(1).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap_err()` + | +LL - let _val = Err::<(), _>(1).unwrap_err(); +LL + let _val = 1; + | + +error: used `expect_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:41:16 + | +LL | let _val = Err::<(), _>(1).expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect_err()` + | +LL - let _val = Err::<(), _>(1).expect_err("this never happens"); +LL + let _val = 1; + | + +error: used `unwrap()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:42:16 + | +LL | let _val = Err::<(), _>(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap()` + | +LL | let _val = panic!("{:?}", 1); + | ~~~~~~~~~~~~~~ ~ + +error: used `expect()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:43:16 + | +LL | let _val = Err::<(), _>(1).expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect()` + | +LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); + | ~~~~~~~~~~~~~~~~~~~ ~ + +error: used `unwrap_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:45:5 + | +LL | Err::<(), _>(1).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap_err()` + | +LL - Err::<(), _>(1).unwrap_err(); +LL + 1; + | + +error: used `expect_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:46:5 + | +LL | Err::<(), _>(1).expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect_err()` + | +LL - Err::<(), _>(1).expect_err("this never happens"); +LL + 1; + | + +error: used `unwrap()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:47:5 + | +LL | Err::<(), _>(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap()` + | +LL | panic!("{:?}", 1); + | ~~~~~~~~~~~~~~ ~ + +error: used `expect()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:48:5 + | +LL | Err::<(), _>(1).expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect()` + | +LL | panic!("{1}: {:?}", 1, "this always happens"); + | ~~~~~~~~~~~~~~~~~~~ ~ + +error: used `unwrap_or()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:52:16 + | +LL | let _val = Some(1).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or()` + | +LL - let _val = Some(1).unwrap_or(2); +LL + let _val = 1; + | + +error: used `unwrap_or_default()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:53:16 + | +LL | let _val = Some(1).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_default()` + | +LL - let _val = Some(1).unwrap_or_default(); +LL + let _val = 1; + | + +error: used `unwrap_or_else()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:54:16 + | +LL | let _val = Some(1).unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_else()` + | +LL - let _val = Some(1).unwrap_or_else(|| 2); +LL + let _val = 1; + | + +error: used `unwrap_or()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:56:5 + | +LL | Some(1).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or()` + | +LL - Some(1).unwrap_or(2); +LL + 1; + | + +error: used `unwrap_or_default()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:57:5 + | +LL | Some(1).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_default()` + | +LL - Some(1).unwrap_or_default(); +LL + 1; + | + +error: used `unwrap_or_else()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:58:5 + | +LL | Some(1).unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_else()` + | +LL - Some(1).unwrap_or_else(|| 2); +LL + 1; + | + +error: used `unwrap_or()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:62:16 + | +LL | let _val = Ok::<_, ()>(1).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or()` + | +LL - let _val = Ok::<_, ()>(1).unwrap_or(2); +LL + let _val = 1; + | + +error: used `unwrap_or_default()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:63:16 + | +LL | let _val = Ok::<_, ()>(1).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_default()` + | +LL - let _val = Ok::<_, ()>(1).unwrap_or_default(); +LL + let _val = 1; + | + +error: used `unwrap_or_else()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:64:16 + | +LL | let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_else()` + | +LL - let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2); +LL + let _val = 1; + | + +error: used `unwrap_or()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:66:5 + | +LL | Ok::<_, ()>(1).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or()` + | +LL - Ok::<_, ()>(1).unwrap_or(2); +LL + 1; + | + +error: used `unwrap_or_default()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:67:5 + | +LL | Ok::<_, ()>(1).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_default()` + | +LL - Ok::<_, ()>(1).unwrap_or_default(); +LL + 1; + | + +error: used `unwrap_or_else()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:68:5 + | +LL | Ok::<_, ()>(1).unwrap_or_else(|_| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_else()` + | +LL - Ok::<_, ()>(1).unwrap_or_else(|_| 2); +LL + 1; + | + +<<<<<<< HEAD +error: aborting due to 36 previous errors +======= + --> $DIR/unnecessary_literal_unwrap.rs:4:15 +======= + --> $DIR/unnecessary_literal_unwrap.rs:5:15 +>>>>>>> daf619748 (Implement the suggestion) +======= + --> $DIR/unnecessary_literal_unwrap.rs:5:16 +>>>>>>> 1d159e7d1 (Recognize `Ok`) + | +LL | let _val = Some(1).unwrap(); + | ^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::unnecessary-literal-unwrap` implied by `-D warnings` +help: remove the `Some` and `unwrap()` + | +LL - let _val = Some(1).unwrap(); +LL + let _val = 1; + | + +<<<<<<< HEAD +error: aborting due to previous error +>>>>>>> 0b1bb5fbf (Implement the lint) +======= +error: used `expect()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:6:16 +======= + --> $DIR/unnecessary_literal_unwrap.rs:7:16 +>>>>>>> 7ed7283e0 (Recognize `unwrap_or_else` method) + | +LL | let _val = Some(1).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `expect()` + | +LL - let _val = Some(1).expect("this never happens"); +LL + let _val = 1; + | + +<<<<<<< HEAD +error: aborting due to 2 previous errors +>>>>>>> 21b88ce29 (Implement the lint for expect) +======= +======= +>>>>>>> 6e4dc93e2 (Support suggesting panics) +error: used `unwrap()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:28:16 + | +LL | let _val = Ok::<_, ()>(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap()` + | +LL - let _val = Ok::<_, ()>(1).unwrap(); +LL + let _val = 1; + | + +error: used `expect()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:29:16 + | +LL | let _val = Ok::<_, ()>(1).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect()` + | +LL - let _val = Ok::<_, ()>(1).expect("this never happens"); +LL + let _val = 1; + | + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 4 previous errors +>>>>>>> 1d159e7d1 (Recognize `Ok`) +======= +error: used `unwrap_or()` on `Some` value +======= +======= +error: used `unwrap_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:30:16 + | +LL | let _val = Ok::<_, ()>(1).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_err()` + | +LL | let _val = panic!("{:?}", 1); + | ~~~~~~~~~~~~~~ ~ + +error: used `expect_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:31:16 + | +LL | let _val = Ok::<_, ()>(1).expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect_err()` + | +LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); + | ~~~~~~~~~~~~~~~~~~~ ~ + +error: used `unwrap()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:33:5 + | +LL | Ok::<_, ()>(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap()` + | +LL - Ok::<_, ()>(1).unwrap(); +LL + 1; + | + +error: used `expect()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:34:5 + | +LL | Ok::<_, ()>(1).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect()` + | +LL - Ok::<_, ()>(1).expect("this never happens"); +LL + 1; + | + +error: used `unwrap_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:35:5 + | +LL | Ok::<_, ()>(1).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_err()` + | +LL | panic!("{:?}", 1); + | ~~~~~~~~~~~~~~ ~ + +error: used `expect_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:36:5 + | +LL | Ok::<_, ()>(1).expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect_err()` + | +LL | panic!("{1}: {:?}", 1, "this always happens"); + | ~~~~~~~~~~~~~~~~~~~ ~ + +>>>>>>> 6e4dc93e2 (Support suggesting panics) +error: used `unwrap_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:40:16 + | +LL | let _val = Err::<(), _>(1).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap_err()` + | +LL - let _val = Err::<(), _>(1).unwrap_err(); +LL + let _val = 1; + | + +error: used `expect_err()` on `Err` value +<<<<<<< HEAD +<<<<<<< HEAD +>>>>>>> 69af0e13b (Recognize `Err`) + --> $DIR/unnecessary_literal_unwrap.rs:17:16 +======= + --> $DIR/unnecessary_literal_unwrap.rs:25:16 +>>>>>>> 6e4dc93e2 (Support suggesting panics) +======= + --> $DIR/unnecessary_literal_unwrap.rs:41:16 +>>>>>>> 6e4c5561b (Preserve type annotations when present) + | +LL | let _val = Err::<(), _>(1).expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect_err()` + | +LL - let _val = Err::<(), _>(1).expect_err("this never happens"); +LL + let _val = 1; + | + +error: used `unwrap()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:42:16 + | +LL | let _val = Err::<(), _>(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap()` + | +LL | let _val = panic!("{:?}", 1); + | ~~~~~~~~~~~~~~ ~ + +error: used `expect()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:43:16 + | +LL | let _val = Err::<(), _>(1).expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect()` + | +LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); + | ~~~~~~~~~~~~~~~~~~~ ~ + +error: used `unwrap_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:45:5 + | +LL | Err::<(), _>(1).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap_err()` + | +LL - Err::<(), _>(1).unwrap_err(); +LL + 1; + | + +error: used `expect_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:46:5 + | +LL | Err::<(), _>(1).expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect_err()` + | +LL - Err::<(), _>(1).expect_err("this never happens"); +LL + 1; + | + +error: used `unwrap()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:47:5 + | +LL | Err::<(), _>(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap()` + | +LL | panic!("{:?}", 1); + | ~~~~~~~~~~~~~~ ~ + +error: used `expect()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:48:5 + | +LL | Err::<(), _>(1).expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect()` + | +LL | panic!("{1}: {:?}", 1, "this always happens"); + | ~~~~~~~~~~~~~~~~~~~ ~ + +error: used `unwrap_or()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:52:16 + | +LL | let _val = Some(1).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or()` + | +LL - let _val = Some(1).unwrap_or(2); +LL + let _val = 1; + | + +error: used `unwrap_or_default()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:53:16 + | +LL | let _val = Some(1).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_default()` + | +LL - let _val = Some(1).unwrap_or_default(); +LL + let _val = 1; + | + +error: used `unwrap_or_else()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:54:16 + | +LL | let _val = Some(1).unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_else()` + | +LL - let _val = Some(1).unwrap_or_else(|| 2); +LL + let _val = 1; + | + +error: used `unwrap_or()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:56:5 + | +LL | Some(1).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or()` + | +LL - Some(1).unwrap_or(2); +LL + 1; + | + +error: used `unwrap_or_default()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:57:5 + | +LL | Some(1).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_default()` + | +LL - Some(1).unwrap_or_default(); +LL + 1; + | + +error: used `unwrap_or_else()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:58:5 + | +LL | Some(1).unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_else()` + | +LL - Some(1).unwrap_or_else(|| 2); +LL + 1; + | + +error: used `unwrap_or()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:62:16 + | +LL | let _val = Ok::<_, ()>(1).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or()` + | +LL - let _val = Ok::<_, ()>(1).unwrap_or(2); +LL + let _val = 1; + | + +error: used `unwrap_or_default()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:63:16 + | +LL | let _val = Ok::<_, ()>(1).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_default()` + | +LL - let _val = Ok::<_, ()>(1).unwrap_or_default(); +LL + let _val = 1; + | + +<<<<<<< HEAD +error: aborting due to 8 previous errors +>>>>>>> 8f8350298 (Recognize `unwrap_or` methods) +======= +error: used `unwrap_or_else()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:64:16 + | +LL | let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_else()` + | +LL - let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2); +LL + let _val = 1; + | + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 10 previous errors +>>>>>>> 7ed7283e0 (Recognize `unwrap_or_else` method) +======= +error: aborting due to 12 previous errors +>>>>>>> 69af0e13b (Recognize `Err`) +======= +error: aborting due to 18 previous errors +>>>>>>> 6e4dc93e2 (Support suggesting panics) +======= +error: used `unwrap_or()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:66:5 + | +LL | Ok::<_, ()>(1).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or()` + | +LL - Ok::<_, ()>(1).unwrap_or(2); +LL + 1; + | + +error: used `unwrap_or_default()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:67:5 + | +LL | Ok::<_, ()>(1).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_default()` + | +LL - Ok::<_, ()>(1).unwrap_or_default(); +LL + 1; + | + +error: used `unwrap_or_else()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:68:5 + | +LL | Ok::<_, ()>(1).unwrap_or_else(|_| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_else()` + | +LL - Ok::<_, ()>(1).unwrap_or_else(|_| 2); +LL + 1; + | + +error: aborting due to 36 previous errors +>>>>>>> 6e4c5561b (Preserve type annotations when present) +======= +error: used `unwrap_unchecked()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:82:22 + | +LL | let _ = unsafe { Some(1).unwrap_unchecked() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_unchecked()` + | +LL - let _ = unsafe { Some(1).unwrap_unchecked() }; +LL + let _ = 1; + | + +error: used `unwrap_unchecked()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:83:22 + | +LL | let _ = unsafe { Some(1).unwrap_unchecked() + *(&1 as *const i32) }; // needs to keep the unsafe block + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_unchecked()` + | +LL - let _ = unsafe { Some(1).unwrap_unchecked() + *(&1 as *const i32) }; // needs to keep the unsafe block +LL + let _ = unsafe { 1 + *(&1 as *const i32) }; // needs to keep the unsafe block + | + +error: used `unwrap_unchecked()` on `Some` value + --> $DIR/unnecessary_literal_unwrap.rs:84:22 + | +LL | let _ = unsafe { Some(1).unwrap_unchecked() } + 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_unchecked()` + | +LL - let _ = unsafe { Some(1).unwrap_unchecked() } + 1; +LL + let _ = 1 + 1; + | + +error: used `unwrap_unchecked()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:85:22 + | +LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_unchecked()` + | +LL - let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() }; +LL + let _ = 1; + | + +error: used `unwrap_unchecked()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:86:22 + | +LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() + *(&1 as *const i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_unchecked()` + | +LL - let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() + *(&1 as *const i32) }; +LL + let _ = unsafe { 1 + *(&1 as *const i32) }; + | + +error: used `unwrap_unchecked()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap.rs:87:22 + | +LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() } + 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_unchecked()` + | +LL - let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() } + 1; +LL + let _ = 1 + 1; + | + +<<<<<<< HEAD +error: aborting due to 42 previous errors +>>>>>>> cd1c8532e ([`unnecessary_literal_unwrap`]: lint `unwrap_unchecked`) +======= +error: used `unwrap_err_unchecked()` on `Err` value + --> $DIR/unnecessary_literal_unwrap.rs:88:22 + | +LL | let _ = unsafe { Err::<(), i32>(123).unwrap_err_unchecked() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap_err_unchecked()` + | +LL - let _ = unsafe { Err::<(), i32>(123).unwrap_err_unchecked() }; +LL + let _ = 123; + | + +error: aborting due to 43 previous errors +>>>>>>> 0b5dac097 ([`unnecessary_literal_unwrap`]: also handle unwrap_err_unchecked) + diff --git a/tests/ui/unnecessary_literal_unwrap_unfixable.rs b/tests/ui/unnecessary_literal_unwrap_unfixable.rs new file mode 100644 index 000000000000..da676a78454b --- /dev/null +++ b/tests/ui/unnecessary_literal_unwrap_unfixable.rs @@ -0,0 +1,239 @@ +#![warn(clippy::unnecessary_literal_unwrap)] +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 6e4c5561b (Preserve type annotations when present) +#![allow(unreachable_code)] +#![allow(clippy::unnecessary_lazy_evaluations, clippy::let_unit_value)] + +fn unwrap_option_some() { + let val = Some(1); + let _val2 = val.unwrap(); + let _val2 = val.expect("this never happens"); +} + +fn unwrap_option_some_context() { + let _val = Some::([1, 2, 3].iter().sum()).unwrap(); + let _val = Some::([1, 2, 3].iter().sum()).expect("this never happens"); + + let val = Some::([1, 2, 3].iter().sum()); + let _val2 = val.unwrap(); + let _val2 = val.expect("this never happens"); +} + +<<<<<<< HEAD +fn unwrap_option_none() { + let val = None::<()>; + let _val2 = val.unwrap(); + let _val2 = val.expect("this always happens"); +} + +fn unwrap_result_ok() { + let val = Ok::<_, ()>(1); + let _val2 = val.unwrap(); + let _val2 = val.expect("this never happens"); + let _val2 = val.unwrap_err(); + let _val2 = val.expect_err("this always happens"); +} + +fn unwrap_result_ok_context() { + let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); + let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); + let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); + let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); + + let val = Ok::([1, 2, 3].iter().sum()); + let _val2 = val.unwrap(); + let _val2 = val.expect("this never happens"); + let _val2 = val.unwrap_err(); + let _val2 = val.expect_err("this always happens"); +} + +fn unwrap_result_err() { + let val = Err::<(), _>(1); + let _val2 = val.unwrap_err(); + let _val2 = val.expect_err("this never happens"); + let _val2 = val.unwrap(); + let _val2 = val.expect("this always happens"); +} + +fn unwrap_result_err_context() { + let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); + let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); + let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); + let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); + + let val = Err::<(), usize>([1, 2, 3].iter().sum()); + let _val2 = val.unwrap_err(); + let _val2 = val.expect_err("this never happens"); + let _val2 = val.unwrap(); + let _val2 = val.expect("this always happens"); +} + +fn unwrap_methods_option() { + let val = Some(1); + let _val2 = val.unwrap_or(2); + let _val2 = val.unwrap_or_default(); + let _val2 = val.unwrap_or_else(|| 2); +} + +fn unwrap_methods_option_context() { + let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); + let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); + let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); + + let val = Some::([1, 2, 3].iter().sum()); + let _val2 = val.unwrap_or(2); + let _val2 = val.unwrap_or_default(); + let _val2 = val.unwrap_or_else(|| 2); +} + +fn unwrap_methods_result() { + let val = Ok::<_, ()>(1); + let _val2 = val.unwrap_or(2); + let _val2 = val.unwrap_or_default(); + let _val2 = val.unwrap_or_else(|_| 2); +} + +fn unwrap_methods_result_context() { + let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); + let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); + let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); + + let val = Ok::([1, 2, 3].iter().sum()); + let _val2 = val.unwrap_or(2); + let _val2 = val.unwrap_or_default(); + let _val2 = val.unwrap_or_else(|_| 2); +} + +fn main() { + unwrap_option_some(); + unwrap_option_some_context(); + unwrap_option_none(); + unwrap_result_ok(); + unwrap_result_ok_context(); + unwrap_result_err(); + unwrap_result_err_context(); + unwrap_methods_option(); + unwrap_methods_option_context(); + unwrap_methods_result(); + unwrap_methods_result_context(); +======= +======= +#![allow(clippy::unnecessary_lazy_evaluations)] +#![allow(unreachable_code)] +>>>>>>> 6cf138e9b (Add more tests) + +fn unwrap_option_some() { + let val = Some(1); + let _val2 = val.unwrap(); +<<<<<<< HEAD +>>>>>>> 6e0e09c8f (Track init and unwrap of expr) +======= + let _val2 = val.expect("this never happens"); +} + +======= +>>>>>>> 6e4c5561b (Preserve type annotations when present) +fn unwrap_option_none() { + let val = None::<()>; + let _val2 = val.unwrap(); + let _val2 = val.expect("this always happens"); +} + +fn unwrap_result_ok() { + let val = Ok::<_, ()>(1); + let _val2 = val.unwrap(); + let _val2 = val.expect("this never happens"); + let _val2 = val.unwrap_err(); + let _val2 = val.expect_err("this always happens"); +} + +fn unwrap_result_ok_context() { + let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); + let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); + let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); + let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); + + let val = Ok::([1, 2, 3].iter().sum()); + let _val2 = val.unwrap(); + let _val2 = val.expect("this never happens"); + let _val2 = val.unwrap_err(); + let _val2 = val.expect_err("this always happens"); +} + +fn unwrap_result_err() { + let val = Err::<(), _>(1); + let _val2 = val.unwrap_err(); + let _val2 = val.expect_err("this never happens"); + let _val2 = val.unwrap(); + let _val2 = val.expect("this always happens"); +} + +fn unwrap_result_err_context() { + let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); + let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); + let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); + let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); + + let val = Err::<(), usize>([1, 2, 3].iter().sum()); + let _val2 = val.unwrap_err(); + let _val2 = val.expect_err("this never happens"); + let _val2 = val.unwrap(); + let _val2 = val.expect("this always happens"); +} + +fn unwrap_methods_option() { + let val = Some(1); + let _val2 = val.unwrap_or(2); + let _val2 = val.unwrap_or_default(); + let _val2 = val.unwrap_or_else(|| 2); +} + +fn unwrap_methods_option_context() { + let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); + let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); + let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); + + let val = Some::([1, 2, 3].iter().sum()); + let _val2 = val.unwrap_or(2); + let _val2 = val.unwrap_or_default(); + let _val2 = val.unwrap_or_else(|| 2); +} + +fn unwrap_methods_result() { + let val = Ok::<_, ()>(1); + let _val2 = val.unwrap_or(2); + let _val2 = val.unwrap_or_default(); + let _val2 = val.unwrap_or_else(|_| 2); +} + +fn unwrap_methods_result_context() { + let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); + let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); + let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); + + let val = Ok::([1, 2, 3].iter().sum()); + let _val2 = val.unwrap_or(2); + let _val2 = val.unwrap_or_default(); + let _val2 = val.unwrap_or_else(|_| 2); +} + +fn main() { + unwrap_option_some(); + unwrap_option_some_context(); + unwrap_option_none(); + unwrap_result_ok(); + unwrap_result_ok_context(); + unwrap_result_err(); + unwrap_result_err_context(); + unwrap_methods_option(); + unwrap_methods_option_context(); + unwrap_methods_result(); +<<<<<<< HEAD +>>>>>>> 6cf138e9b (Add more tests) +======= + unwrap_methods_result_context(); +>>>>>>> 6e4c5561b (Preserve type annotations when present) +} diff --git a/tests/ui/unnecessary_literal_unwrap_unfixable.stderr b/tests/ui/unnecessary_literal_unwrap_unfixable.stderr new file mode 100644 index 000000000000..516eb0fa7e3f --- /dev/null +++ b/tests/ui/unnecessary_literal_unwrap_unfixable.stderr @@ -0,0 +1,1218 @@ +error: used `unwrap()` on `Some` value +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:7:17 +======= + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:5:17 +>>>>>>> 6e0e09c8f (Track init and unwrap of expr) +======= + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:7:17 +>>>>>>> 6cf138e9b (Add more tests) + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap()` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:6:15 +======= + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:4:15 +>>>>>>> 6e0e09c8f (Track init and unwrap of expr) +======= + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:6:15 +>>>>>>> 6cf138e9b (Add more tests) + | +LL | let val = Some(1); + | ^^^^^^^ + = note: `-D clippy::unnecessary-literal-unwrap` implied by `-D warnings` + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 6cf138e9b (Add more tests) +error: used `expect()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:8:17 + | +LL | let _val2 = val.expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:6:15 + | +LL | let val = Some(1); + | ^^^^^^^ + +<<<<<<< HEAD +<<<<<<< HEAD +error: used `unwrap()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:12:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:12:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:13:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:13:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:16:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:15:15 + | +LL | let val = Some::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:17:17 + | +LL | let _val2 = val.expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:15:15 + | +LL | let val = Some::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `None` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:22:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `None` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:21:15 + | +LL | let val = None::<()>; + | ^^^^^^^^^^ + +error: used `expect()` on `None` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:23:17 + | +LL | let _val2 = val.expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:21:15 + | +LL | let val = None::<()>; + | ^^^^^^^^^^ + +error: used `unwrap()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:28:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `expect()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:29:17 + | +LL | let _val2 = val.expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:30:17 + | +LL | let _val2 = val.unwrap_err(); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:31:17 + | +LL | let _val2 = val.expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:35:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:35:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:36:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:36:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:37:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:37:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:38:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:38:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:41:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:17 + | +LL | let _val2 = val.expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:43:17 + | +LL | let _val2 = val.unwrap_err(); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:44:17 + | +LL | let _val2 = val.expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:49:17 + | +LL | let _val2 = val.unwrap_err(); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + | +LL | let val = Err::<(), _>(1); + | ^^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:50:17 + | +LL | let _val2 = val.expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + | +LL | let val = Err::<(), _>(1); + | ^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:51:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + | +LL | let val = Err::<(), _>(1); + | ^^^^^^^^^^^^^^^ + +error: used `expect()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:52:17 + | +LL | let _val2 = val.expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + | +LL | let val = Err::<(), _>(1); + | ^^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:56:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:56:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:57:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:57:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:58:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:58:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:59:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:59:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:62:17 + | +LL | let _val2 = val.unwrap_err(); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + | +LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:17 + | +LL | let _val2 = val.expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + | +LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:64:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + | +LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:65:17 + | +LL | let _val2 = val.expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + | +LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:70:17 + | +LL | let _val2 = val.unwrap_or(2); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:69:15 + | +LL | let val = Some(1); + | ^^^^^^^ + +error: used `unwrap_or_default()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:71:17 + | +LL | let _val2 = val.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:69:15 + | +LL | let val = Some(1); + | ^^^^^^^ + +error: used `unwrap_or_else()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:72:17 + | +LL | let _val2 = val.unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_else()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:69:15 + | +LL | let val = Some(1); + | ^^^^^^^ + +error: used `unwrap_or()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:76:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:76:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_default()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:77:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:77:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_else()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:78:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_else()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:78:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:81:17 + | +LL | let _val2 = val.unwrap_or(2); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:15 + | +LL | let val = Some::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_default()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:82:17 + | +LL | let _val2 = val.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:15 + | +LL | let val = Some::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_else()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:83:17 + | +LL | let _val2 = val.unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_else()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:15 + | +LL | let val = Some::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:88:17 + | +LL | let _val2 = val.unwrap_or(2); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:87:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `unwrap_or_default()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:89:17 + | +LL | let _val2 = val.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:87:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `unwrap_or_else()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:90:17 + | +======= +error: used `unwrap()` on `None` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:13:5 +======= +error: used `unwrap()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:12:16 +>>>>>>> 6e4c5561b (Preserve type annotations when present) + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:12:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:13:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:13:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:16:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:15:15 + | +LL | let val = Some::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:17:17 + | +LL | let _val2 = val.expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:15:15 + | +LL | let val = Some::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `None` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:22:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `None` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:21:15 + | +LL | let val = None::<()>; + | ^^^^^^^^^^ + +error: used `expect()` on `None` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:23:17 + | +LL | let _val2 = val.expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:21:15 + | +LL | let val = None::<()>; + | ^^^^^^^^^^ + +error: used `unwrap()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:28:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `expect()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:29:17 + | +LL | let _val2 = val.expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:30:17 + | +LL | let _val2 = val.unwrap_err(); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:31:17 + | +LL | let _val2 = val.expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:35:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:35:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:36:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:36:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:37:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:37:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:38:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:38:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:41:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:17 + | +LL | let _val2 = val.expect("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:43:17 + | +LL | let _val2 = val.unwrap_err(); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:44:17 + | +LL | let _val2 = val.expect_err("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:49:17 + | +LL | let _val2 = val.unwrap_err(); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + | +LL | let val = Err::<(), _>(1); + | ^^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:50:17 + | +LL | let _val2 = val.expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + | +LL | let val = Err::<(), _>(1); + | ^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:51:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + | +LL | let val = Err::<(), _>(1); + | ^^^^^^^^^^^^^^^ + +error: used `expect()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:52:17 + | +LL | let _val2 = val.expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + | +LL | let val = Err::<(), _>(1); + | ^^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:56:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:56:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:57:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:57:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:58:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:58:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:59:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:59:16 + | +LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:62:17 + | +LL | let _val2 = val.unwrap_err(); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + | +LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect_err()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:17 + | +LL | let _val2 = val.expect_err("this never happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect_err()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + | +LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:64:17 + | +LL | let _val2 = val.unwrap(); + | ^^^^^^^^^^^^ + | +help: remove the `Err` and `unwrap()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + | +LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `expect()` on `Err` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:65:17 + | +LL | let _val2 = val.expect("this always happens"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Err` and `expect()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + | +LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:70:17 + | +LL | let _val2 = val.unwrap_or(2); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:69:15 + | +LL | let val = Some(1); + | ^^^^^^^ + +error: used `unwrap_or_default()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:71:17 + | +LL | let _val2 = val.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:69:15 + | +LL | let val = Some(1); + | ^^^^^^^ + +error: used `unwrap_or_else()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:72:17 + | +LL | let _val2 = val.unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_else()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:69:15 + | +LL | let val = Some(1); + | ^^^^^^^ + +error: used `unwrap_or()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:76:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:76:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_default()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:77:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:77:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_else()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:78:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_else()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:78:16 + | +LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:81:17 + | +LL | let _val2 = val.unwrap_or(2); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:15 + | +LL | let val = Some::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_default()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:82:17 + | +LL | let _val2 = val.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:15 + | +LL | let val = Some::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_else()` on `Some` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:83:17 + | +LL | let _val2 = val.unwrap_or_else(|| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Some` and `unwrap_or_else()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:15 + | +LL | let val = Some::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:88:17 + | +LL | let _val2 = val.unwrap_or(2); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:87:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `unwrap_or_default()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:89:17 + | +LL | let _val2 = val.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:87:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `unwrap_or_else()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:90:17 + | +>>>>>>> 6cf138e9b (Add more tests) +LL | let _val2 = val.unwrap_or_else(|_| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_else()` +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:87:15 + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +error: used `unwrap_or()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:94:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:94:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_default()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:95:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:95:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_else()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:96:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_else()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:96:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:99:17 + | +LL | let _val2 = val.unwrap_or(2); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_default()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:100:17 + | +LL | let _val2 = val.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_else()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:101:17 + | +LL | let _val2 = val.unwrap_or_else(|_| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_else()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 50 previous errors +======= +error: aborting due to previous error +>>>>>>> 6e0e09c8f (Track init and unwrap of expr) +======= + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:41:15 +======= + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:87:15 +>>>>>>> 6e4c5561b (Preserve type annotations when present) + | +LL | let val = Ok::<_, ()>(1); + | ^^^^^^^^^^^^^^ + +<<<<<<< HEAD +error: aborting due to 18 previous errors +>>>>>>> 6cf138e9b (Add more tests) +======= +error: used `unwrap_or()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:94:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:94:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_default()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:95:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:95:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_else()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:96:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_else()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:96:16 + | +LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:99:17 + | +LL | let _val2 = val.unwrap_or(2); + | ^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_default()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:100:17 + | +LL | let _val2 = val.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_default()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: used `unwrap_or_else()` on `Ok` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:101:17 + | +LL | let _val2 = val.unwrap_or_else(|_| 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `Ok` and `unwrap_or_else()` + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:15 + | +LL | let val = Ok::([1, 2, 3].iter().sum()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 50 previous errors +>>>>>>> 6e4c5561b (Preserve type annotations when present) + diff --git a/tests/ui/unnecessary_operation.fixed b/tests/ui/unnecessary_operation.fixed index b046694f8c6f..fbd2d34591fc 100644 --- a/tests/ui/unnecessary_operation.fixed +++ b/tests/ui/unnecessary_operation.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( clippy::deref_addrof, diff --git a/tests/ui/unnecessary_operation.rs b/tests/ui/unnecessary_operation.rs index 9ed9679e938b..b45298a6dc46 100644 --- a/tests/ui/unnecessary_operation.rs +++ b/tests/ui/unnecessary_operation.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( clippy::deref_addrof, diff --git a/tests/ui/unnecessary_owned_empty_strings.fixed b/tests/ui/unnecessary_owned_empty_strings.fixed index 40052c41039e..af12fd1d63d0 100644 --- a/tests/ui/unnecessary_owned_empty_strings.fixed +++ b/tests/ui/unnecessary_owned_empty_strings.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_owned_empty_strings)] diff --git a/tests/ui/unnecessary_owned_empty_strings.rs b/tests/ui/unnecessary_owned_empty_strings.rs index 2304dff5192b..a460b21af8c2 100644 --- a/tests/ui/unnecessary_owned_empty_strings.rs +++ b/tests/ui/unnecessary_owned_empty_strings.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_owned_empty_strings)] diff --git a/tests/ui/unnecessary_safety_comment.rs b/tests/ui/unnecessary_safety_comment.rs index 89fedb145f88..d858701ae8ac 100644 --- a/tests/ui/unnecessary_safety_comment.rs +++ b/tests/ui/unnecessary_safety_comment.rs @@ -1,5 +1,5 @@ #![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)] -#![allow(clippy::let_unit_value, clippy::missing_safety_doc)] +#![allow(clippy::let_unit_value, clippy::missing_safety_doc, clippy::needless_if)] mod unsafe_items_invalid_comment { // SAFETY: diff --git a/tests/ui/unnecessary_self_imports.fixed b/tests/ui/unnecessary_self_imports.fixed index 1185eaa1d552..7fc978d3ef7e 100644 --- a/tests/ui/unnecessary_self_imports.fixed +++ b/tests/ui/unnecessary_self_imports.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_self_imports)] #![allow(unused_imports, dead_code)] diff --git a/tests/ui/unnecessary_self_imports.rs b/tests/ui/unnecessary_self_imports.rs index 56bfbc09402a..02424bc12b00 100644 --- a/tests/ui/unnecessary_self_imports.rs +++ b/tests/ui/unnecessary_self_imports.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_self_imports)] #![allow(unused_imports, dead_code)] diff --git a/tests/ui/unnecessary_sort_by.fixed b/tests/ui/unnecessary_sort_by.fixed index 21e2da474a82..19380ad00dcd 100644 --- a/tests/ui/unnecessary_sort_by.fixed +++ b/tests/ui/unnecessary_sort_by.fixed @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix -#![allow(clippy::stable_sort_primitive)] +#![allow(clippy::stable_sort_primitive, clippy::useless_vec)] use std::cell::Ref; diff --git a/tests/ui/unnecessary_sort_by.rs b/tests/ui/unnecessary_sort_by.rs index 3365bf6e119e..cea1b65b5203 100644 --- a/tests/ui/unnecessary_sort_by.rs +++ b/tests/ui/unnecessary_sort_by.rs @@ -1,6 +1,6 @@ -// run-rustfix +//@run-rustfix -#![allow(clippy::stable_sort_primitive)] +#![allow(clippy::stable_sort_primitive, clippy::useless_vec)] use std::cell::Ref; diff --git a/tests/ui/unnecessary_struct_initialization.fixed b/tests/ui/unnecessary_struct_initialization.fixed index b47129e4a36a..67c67bcc8bdb 100644 --- a/tests/ui/unnecessary_struct_initialization.fixed +++ b/tests/ui/unnecessary_struct_initialization.fixed @@ -1,6 +1,14 @@ -// run-rustfix - -#![allow(unused)] +//@run-rustfix + +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::incorrect_clone_impl_on_copy_type, unused)] +======= +#![allow(clippy::needless_clone_impl, unused)] +>>>>>>> 67d5e6ec3 (add lint [`needless_clone_impl`]) +======= +#![allow(clippy::incorrect_clone_impl_on_copy_type, unused)] +>>>>>>> 10cc1684c (rename lint and disallow `clone_from`) #![warn(clippy::unnecessary_struct_initialization)] struct S { diff --git a/tests/ui/unnecessary_struct_initialization.rs b/tests/ui/unnecessary_struct_initialization.rs index 63b11c626e5b..c8ebb7b30d34 100644 --- a/tests/ui/unnecessary_struct_initialization.rs +++ b/tests/ui/unnecessary_struct_initialization.rs @@ -1,6 +1,14 @@ -// run-rustfix - -#![allow(unused)] +//@run-rustfix + +<<<<<<< HEAD +<<<<<<< HEAD +#![allow(clippy::incorrect_clone_impl_on_copy_type, unused)] +======= +#![allow(clippy::needless_clone_impl, unused)] +>>>>>>> 67d5e6ec3 (add lint [`needless_clone_impl`]) +======= +#![allow(clippy::incorrect_clone_impl_on_copy_type, unused)] +>>>>>>> 10cc1684c (rename lint and disallow `clone_from`) #![warn(clippy::unnecessary_struct_initialization)] struct S { diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed index 345f6d604c4f..cb7562351e8e 100644 --- a/tests/ui/unnecessary_to_owned.fixed +++ b/tests/ui/unnecessary_to_owned.fixed @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::needless_borrow, clippy::ptr_arg)] -#![warn(clippy::unnecessary_to_owned)] +#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)] use std::borrow::Cow; use std::ffi::{CStr, CString, OsStr, OsString}; @@ -474,3 +474,37 @@ mod issue_10021 { Ok(()) } } + +mod issue_10033 { + #![allow(dead_code)] + use std::fmt::Display; + use std::ops::Deref; + + fn _main() { + let f = Foo; + + // Not actually unnecessary - this calls `Foo`'s `Display` impl, not `str`'s (even though `Foo` does + // deref to `str`) + foo(&f.to_string()); + } + + fn foo(s: &str) { + println!("{}", s); + } + + struct Foo; + + impl Deref for Foo { + type Target = str; + + fn deref(&self) -> &Self::Target { + "str" + } + } + + impl Display for Foo { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Foo") + } + } +} diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs index 7eb53df39e5b..f82ddb2d25df 100644 --- a/tests/ui/unnecessary_to_owned.rs +++ b/tests/ui/unnecessary_to_owned.rs @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::needless_borrow, clippy::ptr_arg)] -#![warn(clippy::unnecessary_to_owned)] +#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)] use std::borrow::Cow; use std::ffi::{CStr, CString, OsStr, OsString}; @@ -474,3 +474,37 @@ mod issue_10021 { Ok(()) } } + +mod issue_10033 { + #![allow(dead_code)] + use std::fmt::Display; + use std::ops::Deref; + + fn _main() { + let f = Foo; + + // Not actually unnecessary - this calls `Foo`'s `Display` impl, not `str`'s (even though `Foo` does + // deref to `str`) + foo(&f.to_string()); + } + + fn foo(s: &str) { + println!("{}", s); + } + + struct Foo; + + impl Deref for Foo { + type Target = str; + + fn deref(&self) -> &Self::Target { + "str" + } + } + + impl Display for Foo { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Foo") + } + } +} diff --git a/tests/ui/unnecessary_unsafety_doc.rs b/tests/ui/unnecessary_unsafety_doc.rs index 431093ab3696..2f247908d37f 100644 --- a/tests/ui/unnecessary_unsafety_doc.rs +++ b/tests/ui/unnecessary_unsafety_doc.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macros.rs +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +//@aux-build:proc_macros.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(clippy::let_unit_value)] #![warn(clippy::unnecessary_safety_doc)] diff --git a/tests/ui/unneeded_field_pattern.rs b/tests/ui/unneeded_field_pattern.rs index fa639aa70d61..48ae1cf66405 100644 --- a/tests/ui/unneeded_field_pattern.rs +++ b/tests/ui/unneeded_field_pattern.rs @@ -1,5 +1,9 @@ +//@aux-build:proc_macros.rs:proc-macro #![warn(clippy::unneeded_field_pattern)] -#[allow(dead_code, unused)] +#![allow(dead_code, unused)] + +#[macro_use] +extern crate proc_macros; struct Foo { a: i32, @@ -19,4 +23,12 @@ fn main() { Foo { b: 0, .. } => {}, // should be OK Foo { .. } => {}, // and the Force might be with this one } + external! { + let f = Foo { a: 0, b: 0, c: 0 }; + match f { + Foo { a: _, b: 0, .. } => {}, + + Foo { a: _, b: _, c: _ } => {}, + } + } } diff --git a/tests/ui/unneeded_field_pattern.stderr b/tests/ui/unneeded_field_pattern.stderr index 6f7c31545696..3f15684986fe 100644 --- a/tests/ui/unneeded_field_pattern.stderr +++ b/tests/ui/unneeded_field_pattern.stderr @@ -1,5 +1,5 @@ error: you matched a field with a wildcard pattern, consider using `..` instead - --> $DIR/unneeded_field_pattern.rs:14:15 + --> $DIR/unneeded_field_pattern.rs:18:15 | LL | Foo { a: _, b: 0, .. } => {}, | ^^^^ @@ -8,7 +8,7 @@ LL | Foo { a: _, b: 0, .. } => {}, = note: `-D clippy::unneeded-field-pattern` implied by `-D warnings` error: all the struct fields are matched to a wildcard pattern, consider using `..` - --> $DIR/unneeded_field_pattern.rs:16:9 + --> $DIR/unneeded_field_pattern.rs:20:9 | LL | Foo { a: _, b: _, c: _ } => {}, | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unneeded_wildcard_pattern.fixed b/tests/ui/unneeded_wildcard_pattern.fixed index 12c3461c9557..019588ca5107 100644 --- a/tests/ui/unneeded_wildcard_pattern.fixed +++ b/tests/ui/unneeded_wildcard_pattern.fixed @@ -1,6 +1,20 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(stmt_expr_attributes)] #![deny(clippy::unneeded_wildcard_pattern)] +#![allow(clippy::needless_if)] +<<<<<<< HEAD + +#[macro_use] +extern crate proc_macros; +======= +>>>>>>> 26f50395b (Add `needless_if` lint) + +#[macro_use] +extern crate proc_macros; fn main() { let t = (0, 1, 2, 3); @@ -42,4 +56,8 @@ fn main() { { if let S(0, ..,) = s {}; } + external! { + let t = (0, 1, 2, 3); + if let (0, _, ..) = t {}; + } } diff --git a/tests/ui/unneeded_wildcard_pattern.rs b/tests/ui/unneeded_wildcard_pattern.rs index 4ac01d5d23b0..2df9a3f9fc65 100644 --- a/tests/ui/unneeded_wildcard_pattern.rs +++ b/tests/ui/unneeded_wildcard_pattern.rs @@ -1,6 +1,20 @@ -// run-rustfix +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macros.rs:proc-macro +======= +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(stmt_expr_attributes)] #![deny(clippy::unneeded_wildcard_pattern)] +#![allow(clippy::needless_if)] +<<<<<<< HEAD + +#[macro_use] +extern crate proc_macros; +======= +>>>>>>> 26f50395b (Add `needless_if` lint) + +#[macro_use] +extern crate proc_macros; fn main() { let t = (0, 1, 2, 3); @@ -42,4 +56,8 @@ fn main() { { if let S(0, .., _, _,) = s {}; } + external! { + let t = (0, 1, 2, 3); + if let (0, _, ..) = t {}; + } } diff --git a/tests/ui/unneeded_wildcard_pattern.stderr b/tests/ui/unneeded_wildcard_pattern.stderr index 716d9ecff89a..35a4ddcd50f4 100644 --- a/tests/ui/unneeded_wildcard_pattern.stderr +++ b/tests/ui/unneeded_wildcard_pattern.stderr @@ -1,89 +1,201 @@ error: this pattern is unneeded as the `..` pattern can match that element - --> $DIR/unneeded_wildcard_pattern.rs:8:18 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:13:18 +======= + --> $DIR/unneeded_wildcard_pattern.rs:9:18 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:13:18 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let (0, .., _) = t {}; | ^^^ help: remove it | note: the lint level is defined here - --> $DIR/unneeded_wildcard_pattern.rs:3:9 + --> $DIR/unneeded_wildcard_pattern.rs:4:9 | LL | #![deny(clippy::unneeded_wildcard_pattern)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this pattern is unneeded as the `..` pattern can match that element - --> $DIR/unneeded_wildcard_pattern.rs:9:16 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:14:16 +======= + --> $DIR/unneeded_wildcard_pattern.rs:10:16 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:14:16 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let (0, _, ..) = t {}; | ^^^ help: remove it error: this pattern is unneeded as the `..` pattern can match that element - --> $DIR/unneeded_wildcard_pattern.rs:10:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:15:13 +======= + --> $DIR/unneeded_wildcard_pattern.rs:11:13 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:15:13 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let (_, .., 0) = t {}; | ^^^ help: remove it error: this pattern is unneeded as the `..` pattern can match that element - --> $DIR/unneeded_wildcard_pattern.rs:11:15 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:16:15 +======= + --> $DIR/unneeded_wildcard_pattern.rs:12:15 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:16:15 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let (.., _, 0) = t {}; | ^^^ help: remove it error: these patterns are unneeded as the `..` pattern can match those elements - --> $DIR/unneeded_wildcard_pattern.rs:12:16 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:17:16 +======= + --> $DIR/unneeded_wildcard_pattern.rs:13:16 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:17:16 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let (0, _, _, ..) = t {}; | ^^^^^^ help: remove them error: these patterns are unneeded as the `..` pattern can match those elements - --> $DIR/unneeded_wildcard_pattern.rs:13:18 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:18:18 +======= + --> $DIR/unneeded_wildcard_pattern.rs:14:18 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:18:18 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let (0, .., _, _) = t {}; | ^^^^^^ help: remove them error: these patterns are unneeded as the `..` pattern can match those elements - --> $DIR/unneeded_wildcard_pattern.rs:22:22 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:27:22 +======= + --> $DIR/unneeded_wildcard_pattern.rs:23:22 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:27:22 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let (0, .., _, _,) = t {}; | ^^^^^^ help: remove them error: this pattern is unneeded as the `..` pattern can match that element - --> $DIR/unneeded_wildcard_pattern.rs:29:19 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:34:19 +======= + --> $DIR/unneeded_wildcard_pattern.rs:30:19 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:34:19 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let S(0, .., _) = s {}; | ^^^ help: remove it error: this pattern is unneeded as the `..` pattern can match that element - --> $DIR/unneeded_wildcard_pattern.rs:30:17 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:35:17 +======= + --> $DIR/unneeded_wildcard_pattern.rs:31:17 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:35:17 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let S(0, _, ..) = s {}; | ^^^ help: remove it error: this pattern is unneeded as the `..` pattern can match that element - --> $DIR/unneeded_wildcard_pattern.rs:31:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:36:14 +======= + --> $DIR/unneeded_wildcard_pattern.rs:32:14 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:36:14 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let S(_, .., 0) = s {}; | ^^^ help: remove it error: this pattern is unneeded as the `..` pattern can match that element - --> $DIR/unneeded_wildcard_pattern.rs:32:16 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:37:16 +======= + --> $DIR/unneeded_wildcard_pattern.rs:33:16 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:37:16 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let S(.., _, 0) = s {}; | ^^^ help: remove it error: these patterns are unneeded as the `..` pattern can match those elements - --> $DIR/unneeded_wildcard_pattern.rs:33:17 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:38:17 +======= + --> $DIR/unneeded_wildcard_pattern.rs:34:17 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:38:17 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let S(0, _, _, ..) = s {}; | ^^^^^^ help: remove them error: these patterns are unneeded as the `..` pattern can match those elements - --> $DIR/unneeded_wildcard_pattern.rs:34:19 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:39:19 +======= + --> $DIR/unneeded_wildcard_pattern.rs:35:19 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:39:19 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let S(0, .., _, _) = s {}; | ^^^^^^ help: remove them error: these patterns are unneeded as the `..` pattern can match those elements - --> $DIR/unneeded_wildcard_pattern.rs:43:23 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unneeded_wildcard_pattern.rs:48:23 +======= + --> $DIR/unneeded_wildcard_pattern.rs:44:23 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unneeded_wildcard_pattern.rs:48:23 +>>>>>>> d29506794 (Don't lint code from external macros) | LL | if let S(0, .., _, _,) = s {}; | ^^^^^^ help: remove them diff --git a/tests/ui/unnested_or_patterns.fixed b/tests/ui/unnested_or_patterns.fixed index 0a8e7b34dfa4..3aee960edee9 100644 --- a/tests/ui/unnested_or_patterns.fixed +++ b/tests/ui/unnested_or_patterns.fixed @@ -1,8 +1,27 @@ -// run-rustfix +//@run-rustfix #![feature(box_patterns)] #![warn(clippy::unnested_or_patterns)] -#![allow(clippy::cognitive_complexity, clippy::match_ref_pats, clippy::upper_case_acronyms)] +#![allow( + clippy::cognitive_complexity, + clippy::match_ref_pats, + clippy::upper_case_acronyms, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::needless_if, + clippy::manual_range_patterns +======= + clippy::needless_if +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + clippy::needless_if, +<<<<<<< HEAD + clippy::manual_range_pattern +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) +======= + clippy::manual_range_patterns +>>>>>>> b592d3996 (manual_range_pattern -> manual_range_patterns) +)] #![allow(unreachable_patterns, irrefutable_let_patterns, unused)] fn main() { diff --git a/tests/ui/unnested_or_patterns.rs b/tests/ui/unnested_or_patterns.rs index 2c454adfe89d..3f522d7bf36b 100644 --- a/tests/ui/unnested_or_patterns.rs +++ b/tests/ui/unnested_or_patterns.rs @@ -1,8 +1,27 @@ -// run-rustfix +//@run-rustfix #![feature(box_patterns)] #![warn(clippy::unnested_or_patterns)] -#![allow(clippy::cognitive_complexity, clippy::match_ref_pats, clippy::upper_case_acronyms)] +#![allow( + clippy::cognitive_complexity, + clippy::match_ref_pats, + clippy::upper_case_acronyms, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::needless_if, + clippy::manual_range_patterns +======= + clippy::needless_if +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + clippy::needless_if, +<<<<<<< HEAD + clippy::manual_range_pattern +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) +======= + clippy::manual_range_patterns +>>>>>>> b592d3996 (manual_range_pattern -> manual_range_patterns) +)] #![allow(unreachable_patterns, irrefutable_let_patterns, unused)] fn main() { diff --git a/tests/ui/unnested_or_patterns.stderr b/tests/ui/unnested_or_patterns.stderr index a1f193db555a..f76f23b7f684 100644 --- a/tests/ui/unnested_or_patterns.stderr +++ b/tests/ui/unnested_or_patterns.stderr @@ -1,5 +1,13 @@ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:12:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:18:12 +======= + --> $DIR/unnested_or_patterns.rs:17:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:18:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let box 0 | box 2 = Box::new(0) {} | ^^^^^^^^^^^^^ @@ -11,7 +19,15 @@ LL | if let box (0 | 2) = Box::new(0) {} | ~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:13:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:19:12 +======= + --> $DIR/unnested_or_patterns.rs:18:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:19:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +38,15 @@ LL | if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:15:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:21:12 +======= + --> $DIR/unnested_or_patterns.rs:20:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:21:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let Some(1) | C0 | Some(2) = None {} | ^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +57,15 @@ LL | if let Some(1 | 2) | C0 = None {} | ~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:16:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:22:12 +======= + --> $DIR/unnested_or_patterns.rs:21:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:22:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let &mut 0 | &mut 2 = &mut 0 {} | ^^^^^^^^^^^^^^^ @@ -44,7 +76,15 @@ LL | if let &mut (0 | 2) = &mut 0 {} | ~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:17:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:23:12 +======= + --> $DIR/unnested_or_patterns.rs:22:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:23:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let x @ 0 | x @ 2 = 0 {} | ^^^^^^^^^^^^^ @@ -55,7 +95,15 @@ LL | if let x @ (0 | 2) = 0 {} | ~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:18:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:24:12 +======= + --> $DIR/unnested_or_patterns.rs:23:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:24:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +114,15 @@ LL | if let (0, 1 | 2 | 3) = (0, 0) {} | ~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:19:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:25:12 +======= + --> $DIR/unnested_or_patterns.rs:24:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:25:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +133,15 @@ LL | if let (1 | 2 | 3, 0) = (0, 0) {} | ~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:20:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:26:12 +======= + --> $DIR/unnested_or_patterns.rs:25:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:26:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -88,7 +152,15 @@ LL | if let (x, ..) | (x, 1 | 2) = (0, 1) {} | ~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:21:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:27:12 +======= + --> $DIR/unnested_or_patterns.rs:26:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:27:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let [0] | [1] = [0] {} | ^^^^^^^^^ @@ -99,7 +171,15 @@ LL | if let [0 | 1] = [0] {} | ~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:22:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:28:12 +======= + --> $DIR/unnested_or_patterns.rs:27:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:28:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let [x, 0] | [x, 1] = [0, 1] {} | ^^^^^^^^^^^^^^^ @@ -110,7 +190,15 @@ LL | if let [x, 0 | 1] = [0, 1] {} | ~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:23:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:29:12 +======= + --> $DIR/unnested_or_patterns.rs:28:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:29:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +209,15 @@ LL | if let [x, 0 | 1 | 2] = [0, 1] {} | ~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:24:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:30:12 +======= + --> $DIR/unnested_or_patterns.rs:29:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:30:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,7 +228,15 @@ LL | if let [x, ..] | [x, 1 | 2] = [0, 1] {} | ~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:26:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:32:12 +======= + --> $DIR/unnested_or_patterns.rs:31:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:32:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let TS(0, x) | TS(1, x) = TS(0, 0) {} | ^^^^^^^^^^^^^^^^^^^ @@ -143,7 +247,15 @@ LL | if let TS(0 | 1, x) = TS(0, 0) {} | ~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:27:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:33:12 +======= + --> $DIR/unnested_or_patterns.rs:32:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:33:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,7 +266,15 @@ LL | if let TS(1 | 2 | 3, 0) = TS(0, 0) {} | ~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:28:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:34:12 +======= + --> $DIR/unnested_or_patterns.rs:33:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:34:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -165,7 +285,15 @@ LL | if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {} | ~~~~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:33:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:39:12 +======= + --> $DIR/unnested_or_patterns.rs:38:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:39:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -176,7 +304,15 @@ LL | if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {} | ~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns.rs:44:12 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unnested_or_patterns.rs:50:12 +======= + --> $DIR/unnested_or_patterns.rs:49:12 +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + --> $DIR/unnested_or_patterns.rs:50:12 +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) | LL | if let [1] | [53] = [0] {} | ^^^^^^^^^^ diff --git a/tests/ui/unnested_or_patterns2.fixed b/tests/ui/unnested_or_patterns2.fixed index d3539d798157..5c04ef1c12df 100644 --- a/tests/ui/unnested_or_patterns2.fixed +++ b/tests/ui/unnested_or_patterns2.fixed @@ -1,8 +1,29 @@ -// run-rustfix +//@run-rustfix #![feature(box_patterns)] #![warn(clippy::unnested_or_patterns)] -#![allow(clippy::cognitive_complexity, clippy::match_ref_pats)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) +#![allow( + clippy::cognitive_complexity, + clippy::match_ref_pats, + clippy::needless_if, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::manual_range_patterns +)] +======= +#![allow(clippy::cognitive_complexity, clippy::match_ref_pats, clippy::needless_if)] +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + clippy::manual_range_pattern +======= + clippy::manual_range_patterns +>>>>>>> b592d3996 (manual_range_pattern -> manual_range_patterns) +)] +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) #![allow(unreachable_patterns, irrefutable_let_patterns, unused_variables)] fn main() { diff --git a/tests/ui/unnested_or_patterns2.rs b/tests/ui/unnested_or_patterns2.rs index 9cea5cdea699..c0740121b2e0 100644 --- a/tests/ui/unnested_or_patterns2.rs +++ b/tests/ui/unnested_or_patterns2.rs @@ -1,8 +1,29 @@ -// run-rustfix +//@run-rustfix #![feature(box_patterns)] #![warn(clippy::unnested_or_patterns)] -#![allow(clippy::cognitive_complexity, clippy::match_ref_pats)] +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) +#![allow( + clippy::cognitive_complexity, + clippy::match_ref_pats, + clippy::needless_if, +<<<<<<< HEAD +<<<<<<< HEAD + clippy::manual_range_patterns +)] +======= +#![allow(clippy::cognitive_complexity, clippy::match_ref_pats, clippy::needless_if)] +>>>>>>> 26f50395b (Add `needless_if` lint) +======= + clippy::manual_range_pattern +======= + clippy::manual_range_patterns +>>>>>>> b592d3996 (manual_range_pattern -> manual_range_patterns) +)] +>>>>>>> 1d4afc5d8 (new lint: `manual_range_pattern`) #![allow(unreachable_patterns, irrefutable_let_patterns, unused_variables)] fn main() { diff --git a/tests/ui/unnested_or_patterns2.stderr b/tests/ui/unnested_or_patterns2.stderr index 41e8d3fc7092..76e890b3a2e3 100644 --- a/tests/ui/unnested_or_patterns2.stderr +++ b/tests/ui/unnested_or_patterns2.stderr @@ -1,5 +1,5 @@ error: unnested or-patterns - --> $DIR/unnested_or_patterns2.rs:9:12 + --> $DIR/unnested_or_patterns2.rs:14:12 | LL | if let Some(Some(0)) | Some(Some(1)) = None {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL | if let Some(Some(0 | 1)) = None {} | ~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns2.rs:10:12 + --> $DIR/unnested_or_patterns2.rs:15:12 | LL | if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | if let Some(Some(0 | 1 | 2)) = None {} | ~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns2.rs:11:12 + --> $DIR/unnested_or_patterns2.rs:16:12 | LL | if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {} | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns2.rs:12:12 + --> $DIR/unnested_or_patterns2.rs:17:12 | LL | if let Some(Some(0) | Some(1 | 2)) = None {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | if let Some(Some(0 | 1 | 2)) = None {} | ~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns2.rs:13:12 + --> $DIR/unnested_or_patterns2.rs:18:12 | LL | if let ((0,),) | ((1,) | (2,),) = ((0,),) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | if let ((0 | 1 | 2,),) = ((0,),) {} | ~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns2.rs:14:12 + --> $DIR/unnested_or_patterns2.rs:19:12 | LL | if let 0 | (1 | 2) = 0 {} | ^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | if let 0 | 1 | 2 = 0 {} | ~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns2.rs:15:12 + --> $DIR/unnested_or_patterns2.rs:20:12 | LL | if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {} | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnested or-patterns - --> $DIR/unnested_or_patterns2.rs:16:12 + --> $DIR/unnested_or_patterns2.rs:21:12 | LL | if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unreadable_literal.fixed b/tests/ui/unreadable_literal.fixed index 13e5feb19263..f5e87648a231 100644 --- a/tests/ui/unreadable_literal.fixed +++ b/tests/ui/unreadable_literal.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unreadable_literal)] #![allow(unused_tuple_struct_fields)] diff --git a/tests/ui/unreadable_literal.rs b/tests/ui/unreadable_literal.rs index 82f04e7ced52..426bdf7d7328 100644 --- a/tests/ui/unreadable_literal.rs +++ b/tests/ui/unreadable_literal.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unreadable_literal)] #![allow(unused_tuple_struct_fields)] diff --git a/tests/ui/unsafe_removed_from_name.rs b/tests/ui/unsafe_removed_from_name.rs index d29888ac62f6..04f6ef29a9a1 100644 --- a/tests/ui/unsafe_removed_from_name.rs +++ b/tests/ui/unsafe_removed_from_name.rs @@ -8,9 +8,13 @@ use std::cell::UnsafeCell as TotallySafeCellAgain; // Shouldn't error use std::cell::RefCell as ProbablyNotUnsafe; + use std::cell::RefCell as RefCellThatCantBeUnsafe; + use std::cell::UnsafeCell as SuperDangerousUnsafeCell; + use std::cell::UnsafeCell as Dangerunsafe; + use std::cell::UnsafeCell as Bombsawayunsafe; mod mod_with_some_unsafe_things { @@ -20,8 +24,12 @@ mod mod_with_some_unsafe_things { use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety; +// merged imports +use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B}; + // Shouldn't error use mod_with_some_unsafe_things::Safe as IPromiseItsSafeThisTime; + use mod_with_some_unsafe_things::Unsafe as SuperUnsafeModThing; #[allow(clippy::unsafe_removed_from_name)] diff --git a/tests/ui/unsafe_removed_from_name.stderr b/tests/ui/unsafe_removed_from_name.stderr index 4f871cbe41b0..090d917bd384 100644 --- a/tests/ui/unsafe_removed_from_name.stderr +++ b/tests/ui/unsafe_removed_from_name.stderr @@ -13,10 +13,22 @@ LL | use std::cell::UnsafeCell as TotallySafeCellAgain; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: removed `unsafe` from the name of `Unsafe` in use as `LieAboutModSafety` - --> $DIR/unsafe_removed_from_name.rs:21:1 + --> $DIR/unsafe_removed_from_name.rs:25:1 | LL | use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: removed `unsafe` from the name of `Unsafe` in use as `A` + --> $DIR/unsafe_removed_from_name.rs:28:1 + | +LL | use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: removed `unsafe` from the name of `Unsafe` in use as `B` + --> $DIR/unsafe_removed_from_name.rs:28:1 + | +LL | use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors diff --git a/tests/ui/unseparated_prefix_literals.fixed b/tests/ui/unseparated_prefix_literals.fixed index f0c2ba7ccdfa..d81722685f36 100644 --- a/tests/ui/unseparated_prefix_literals.fixed +++ b/tests/ui/unseparated_prefix_literals.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::unseparated_literal_suffix)] #![allow(dead_code)] diff --git a/tests/ui/unseparated_prefix_literals.rs b/tests/ui/unseparated_prefix_literals.rs index f44880b41475..5204d4ac201d 100644 --- a/tests/ui/unseparated_prefix_literals.rs +++ b/tests/ui/unseparated_prefix_literals.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::unseparated_literal_suffix)] #![allow(dead_code)] diff --git a/tests/ui/unused_async.rs b/tests/ui/unused_async.rs index 4ca7f29b34cd..5baa785f9fe6 100644 --- a/tests/ui/unused_async.rs +++ b/tests/ui/unused_async.rs @@ -1,8 +1,51 @@ #![warn(clippy::unused_async)] +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] use std::future::Future; use std::pin::Pin; +mod issue10800 { + #![allow(dead_code, unused_must_use, clippy::no_effect)] + + use std::future::ready; + + async fn async_block_await() { + async { + ready(()).await; + }; + } + + async fn normal_block_await() { + { + { + ready(()).await; + } + } + } +} + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a43bfefd1 ([`unused_async`]: don't lint on async trait impls) +mod issue10459 { + trait HasAsyncMethod { + async fn do_something() -> u32; + } + + impl HasAsyncMethod for () { + async fn do_something() -> u32 { + 1 + } + } +} + +<<<<<<< HEAD +======= +>>>>>>> 1e73a9eb4 (do not consider `await` in nested `async` blocks) +======= +>>>>>>> a43bfefd1 ([`unused_async`]: don't lint on async trait impls) async fn foo() -> i32 { 4 } diff --git a/tests/ui/unused_async.stderr b/tests/ui/unused_async.stderr index cff3eccbd32b..610d49c11639 100644 --- a/tests/ui/unused_async.stderr +++ b/tests/ui/unused_async.stderr @@ -1,5 +1,50 @@ error: unused `async` for function with no await statements - --> $DIR/unused_async.rs:6:1 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unused_async.rs:13:5 +======= + --> $DIR/unused_async.rs:11:5 +>>>>>>> 1e73a9eb4 (do not consider `await` in nested `async` blocks) +======= + --> $DIR/unused_async.rs:13:5 +>>>>>>> a43bfefd1 ([`unused_async`]: don't lint on async trait impls) + | +LL | / async fn async_block_await() { +LL | | async { +LL | | ready(()).await; +LL | | }; +LL | | } + | |_____^ + | + = help: consider removing the `async` from this function +<<<<<<< HEAD +<<<<<<< HEAD +note: `await` used in an async block, which does not require the enclosing function to be `async` + --> $DIR/unused_async.rs:15:23 + | +LL | ready(()).await; + | ^^^^^ + = note: `-D clippy::unused-async` implied by `-D warnings` + +error: unused `async` for function with no await statements + --> $DIR/unused_async.rs:40:1 +<<<<<<< HEAD +======= + = note: `await` used in an async block, which does not require the enclosing function to be `async` +======= +note: `await` used in an async block, which does not require the enclosing function to be `async` + --> $DIR/unused_async.rs:13:23 + | +LL | ready(()).await; + | ^^^^^ +>>>>>>> 8ef6240af (point to `await` expr in note) + = note: `-D clippy::unused-async` implied by `-D warnings` + +error: unused `async` for function with no await statements + --> $DIR/unused_async.rs:26:1 +>>>>>>> 1e73a9eb4 (do not consider `await` in nested `async` blocks) +======= +>>>>>>> a43bfefd1 ([`unused_async`]: don't lint on async trait impls) | LL | / async fn foo() -> i32 { LL | | 4 @@ -7,10 +52,17 @@ LL | | } | |_^ | = help: consider removing the `async` from this function - = note: `-D clippy::unused-async` implied by `-D warnings` error: unused `async` for function with no await statements - --> $DIR/unused_async.rs:17:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/unused_async.rs:51:5 +======= + --> $DIR/unused_async.rs:37:5 +>>>>>>> 1e73a9eb4 (do not consider `await` in nested `async` blocks) +======= + --> $DIR/unused_async.rs:51:5 +>>>>>>> a43bfefd1 ([`unused_async`]: don't lint on async trait impls) | LL | / async fn unused(&self) -> i32 { LL | | 1 @@ -19,5 +71,5 @@ LL | | } | = help: consider removing the `async` from this function -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/unused_io_amount.rs b/tests/ui/unused_io_amount.rs index 8d3e094b7596..e9d1eeb31612 100644 --- a/tests/ui/unused_io_amount.rs +++ b/tests/ui/unused_io_amount.rs @@ -1,4 +1,4 @@ -#![allow(dead_code)] +#![allow(dead_code, clippy::needless_pass_by_ref_mut)] #![warn(clippy::unused_io_amount)] extern crate futures; diff --git a/tests/ui/unused_peekable.rs b/tests/ui/unused_peekable.rs index 7374dfdf92e8..b227f8660f53 100644 --- a/tests/ui/unused_peekable.rs +++ b/tests/ui/unused_peekable.rs @@ -1,8 +1,7 @@ #![warn(clippy::unused_peekable)] #![allow(clippy::no_effect)] -use std::iter::Empty; -use std::iter::Peekable; +use std::iter::{Empty, Peekable}; fn main() { invalid(); diff --git a/tests/ui/unused_peekable.stderr b/tests/ui/unused_peekable.stderr index 54788f2fa2f4..d969232fdf3b 100644 --- a/tests/ui/unused_peekable.stderr +++ b/tests/ui/unused_peekable.stderr @@ -1,5 +1,5 @@ error: `peek` never called on `Peekable` iterator - --> $DIR/unused_peekable.rs:14:9 + --> $DIR/unused_peekable.rs:13:9 | LL | let peekable = std::iter::empty::().peekable(); | ^^^^^^^^ @@ -8,7 +8,7 @@ LL | let peekable = std::iter::empty::().peekable(); = note: `-D clippy::unused-peekable` implied by `-D warnings` error: `peek` never called on `Peekable` iterator - --> $DIR/unused_peekable.rs:18:9 + --> $DIR/unused_peekable.rs:17:9 | LL | let new_local = old_local; | ^^^^^^^^^ @@ -16,7 +16,7 @@ LL | let new_local = old_local; = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> $DIR/unused_peekable.rs:22:9 + --> $DIR/unused_peekable.rs:21:9 | LL | let by_mut_ref = &mut by_mut_ref_test; | ^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | let by_mut_ref = &mut by_mut_ref_test; = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> $DIR/unused_peekable.rs:29:9 + --> $DIR/unused_peekable.rs:28:9 | LL | let peekable_from_fn = returns_peekable(); | ^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | let peekable_from_fn = returns_peekable(); = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> $DIR/unused_peekable.rs:32:13 + --> $DIR/unused_peekable.rs:31:13 | LL | let mut peekable_using_iterator_method = std::iter::empty::().peekable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | let mut peekable_using_iterator_method = std::iter::empty::().peek = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> $DIR/unused_peekable.rs:37:9 + --> $DIR/unused_peekable.rs:36:9 | LL | let passed_along_ref = std::iter::empty::().peekable(); | ^^^^^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | let passed_along_ref = std::iter::empty::().peekable(); = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> $DIR/unused_peekable.rs:42:9 + --> $DIR/unused_peekable.rs:41:9 | LL | let _by_ref = by_ref_test.by_ref(); | ^^^^^^^ @@ -56,7 +56,7 @@ LL | let _by_ref = by_ref_test.by_ref(); = help: consider removing the call to `peekable` error: `peek` never called on `Peekable` iterator - --> $DIR/unused_peekable.rs:44:13 + --> $DIR/unused_peekable.rs:43:13 | LL | let mut peekable_in_for_loop = std::iter::empty::().peekable(); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unused_rounding.fixed b/tests/ui/unused_rounding.fixed index f6f734c05ed5..f02b55502a06 100644 --- a/tests/ui/unused_rounding.fixed +++ b/tests/ui/unused_rounding.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unused_rounding)] fn main() { diff --git a/tests/ui/unused_rounding.rs b/tests/ui/unused_rounding.rs index a0267d8144aa..c7bd4906d0b7 100644 --- a/tests/ui/unused_rounding.rs +++ b/tests/ui/unused_rounding.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unused_rounding)] fn main() { diff --git a/tests/ui/unused_unit.fixed b/tests/ui/unused_unit.fixed index 3dd640b86f0b..7b8f7847dbf6 100644 --- a/tests/ui/unused_unit.fixed +++ b/tests/ui/unused_unit.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // The output for humans should just highlight the whole span without showing // the suggested replacement, but we also want to test that suggested diff --git a/tests/ui/unused_unit.rs b/tests/ui/unused_unit.rs index bddecf06fb76..fdde1ecadf0b 100644 --- a/tests/ui/unused_unit.rs +++ b/tests/ui/unused_unit.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // The output for humans should just highlight the whole span without showing // the suggested replacement, but we also want to test that suggested diff --git a/tests/ui/unwrap.rs b/tests/ui/unwrap.rs index d9fd402e7cfb..64d6437834e6 100644 --- a/tests/ui/unwrap.rs +++ b/tests/ui/unwrap.rs @@ -1,4 +1,5 @@ #![warn(clippy::unwrap_used)] +#![allow(clippy::unnecessary_literal_unwrap)] fn unwrap_option() { let opt = Some(0); diff --git a/tests/ui/unwrap.stderr b/tests/ui/unwrap.stderr index d49bf2b32283..3796d942ff9f 100644 --- a/tests/ui/unwrap.stderr +++ b/tests/ui/unwrap.stderr @@ -1,5 +1,5 @@ error: used `unwrap()` on an `Option` value - --> $DIR/unwrap.rs:5:13 + --> $DIR/unwrap.rs:6:13 | LL | let _ = opt.unwrap(); | ^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let _ = opt.unwrap(); = note: `-D clippy::unwrap-used` implied by `-D warnings` error: used `unwrap()` on a `Result` value - --> $DIR/unwrap.rs:10:13 + --> $DIR/unwrap.rs:11:13 | LL | let _ = res.unwrap(); | ^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | let _ = res.unwrap(); = help: if you don't want to handle the `Err` case gracefully, consider using `expect()` to provide a better panic message error: used `unwrap_err()` on a `Result` value - --> $DIR/unwrap.rs:11:13 + --> $DIR/unwrap.rs:12:13 | LL | let _ = res.unwrap_err(); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unwrap_expect_used.rs b/tests/ui/unwrap_expect_used.rs index 9f27fef82494..7f57efc53c9c 100644 --- a/tests/ui/unwrap_expect_used.rs +++ b/tests/ui/unwrap_expect_used.rs @@ -1,4 +1,5 @@ #![warn(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unnecessary_literal_unwrap)] trait OptionExt { type Item; diff --git a/tests/ui/unwrap_expect_used.stderr b/tests/ui/unwrap_expect_used.stderr index fe4ecef11453..1a551ab5ab8e 100644 --- a/tests/ui/unwrap_expect_used.stderr +++ b/tests/ui/unwrap_expect_used.stderr @@ -1,5 +1,5 @@ error: used `unwrap()` on an `Option` value - --> $DIR/unwrap_expect_used.rs:23:5 + --> $DIR/unwrap_expect_used.rs:24:5 | LL | Some(3).unwrap(); | ^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | Some(3).unwrap(); = note: `-D clippy::unwrap-used` implied by `-D warnings` error: used `expect()` on an `Option` value - --> $DIR/unwrap_expect_used.rs:24:5 + --> $DIR/unwrap_expect_used.rs:25:5 | LL | Some(3).expect("Hello world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | Some(3).expect("Hello world!"); = note: `-D clippy::expect-used` implied by `-D warnings` error: used `unwrap()` on a `Result` value - --> $DIR/unwrap_expect_used.rs:31:5 + --> $DIR/unwrap_expect_used.rs:32:5 | LL | a.unwrap(); | ^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | a.unwrap(); = help: if this value is an `Err`, it will panic error: used `expect()` on a `Result` value - --> $DIR/unwrap_expect_used.rs:32:5 + --> $DIR/unwrap_expect_used.rs:33:5 | LL | a.expect("Hello world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | a.expect("Hello world!"); = help: if this value is an `Err`, it will panic error: used `unwrap_err()` on a `Result` value - --> $DIR/unwrap_expect_used.rs:33:5 + --> $DIR/unwrap_expect_used.rs:34:5 | LL | a.unwrap_err(); | ^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | a.unwrap_err(); = help: if this value is an `Ok`, it will panic error: used `expect_err()` on a `Result` value - --> $DIR/unwrap_expect_used.rs:34:5 + --> $DIR/unwrap_expect_used.rs:35:5 | LL | a.expect_err("Hello error!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unwrap_or.rs b/tests/ui/unwrap_or.rs index a0c003f5b1ea..5bea85e66924 100644 --- a/tests/ui/unwrap_or.rs +++ b/tests/ui/unwrap_or.rs @@ -1,4 +1,5 @@ #![warn(clippy::all, clippy::or_fun_call)] +#![allow(clippy::unnecessary_literal_unwrap)] fn main() { let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len(); diff --git a/tests/ui/unwrap_or.stderr b/tests/ui/unwrap_or.stderr index c3a7464fd470..e384bbbb0155 100644 --- a/tests/ui/unwrap_or.stderr +++ b/tests/ui/unwrap_or.stderr @@ -1,16 +1,16 @@ error: use of `unwrap_or` followed by a function call - --> $DIR/unwrap_or.rs:4:47 + --> $DIR/unwrap_or.rs:5:47 | LL | let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "Fail".to_string())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| "Fail".to_string())` | = note: `-D clippy::or-fun-call` implied by `-D warnings` error: use of `unwrap_or` followed by a function call - --> $DIR/unwrap_or.rs:8:47 + --> $DIR/unwrap_or.rs:9:47 | LL | let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "Fail".to_string())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| "Fail".to_string())` error: aborting due to 2 previous errors diff --git a/tests/ui/unwrap_or_else_default.fixed b/tests/ui/unwrap_or_else_default.fixed index 84f779569ff9..08b89a18bbbd 100644 --- a/tests/ui/unwrap_or_else_default.fixed +++ b/tests/ui/unwrap_or_else_default.fixed @@ -1,8 +1,8 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unwrap_or_else_default)] #![allow(dead_code)] -#![allow(clippy::unnecessary_wraps)] +#![allow(clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)] /// Checks implementation of the `UNWRAP_OR_ELSE_DEFAULT` lint. fn unwrap_or_else_default() { diff --git a/tests/ui/unwrap_or_else_default.rs b/tests/ui/unwrap_or_else_default.rs index 1735bd5808e5..ad2a744908fc 100644 --- a/tests/ui/unwrap_or_else_default.rs +++ b/tests/ui/unwrap_or_else_default.rs @@ -1,8 +1,8 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unwrap_or_else_default)] #![allow(dead_code)] -#![allow(clippy::unnecessary_wraps)] +#![allow(clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)] /// Checks implementation of the `UNWRAP_OR_ELSE_DEFAULT` lint. fn unwrap_or_else_default() { diff --git a/tests/ui/update-all-references.sh b/tests/ui/update-all-references.sh index 4391499a1e1f..d42043070261 100755 --- a/tests/ui/update-all-references.sh +++ b/tests/ui/update-all-references.sh @@ -1,3 +1,3 @@ #!/bin/bash -echo "Please use 'cargo dev bless' instead." +echo "Please use 'cargo bless' instead." diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index 3ac6217312a8..284911743450 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::use_self)] #![allow(dead_code, unreachable_code)] diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index 9dc5d1e3f9b2..ff3b7e369560 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![warn(clippy::use_self)] #![allow(dead_code, unreachable_code)] diff --git a/tests/ui/use_self_trait.fixed b/tests/ui/use_self_trait.fixed index 4e779308d024..20138a29fd1f 100644 --- a/tests/ui/use_self_trait.fixed +++ b/tests/ui/use_self_trait.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::use_self)] #![allow(dead_code)] @@ -33,7 +33,7 @@ impl SelfTrait for Bad { fn nested(_p1: Box, _p2: (&u8, &Self)) {} fn vals(_: Self) -> Self { - Self::default() + Self } } @@ -70,7 +70,7 @@ impl SelfTrait for Good { fn nested(_p1: Box, _p2: (&u8, &Self)) {} fn vals(_: Self) -> Self { - Self::default() + Self } } diff --git a/tests/ui/use_self_trait.rs b/tests/ui/use_self_trait.rs index 325dc73b21ea..bf697b01a42f 100644 --- a/tests/ui/use_self_trait.rs +++ b/tests/ui/use_self_trait.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::use_self)] #![allow(dead_code)] @@ -33,7 +33,7 @@ impl SelfTrait for Bad { fn nested(_p1: Box, _p2: (&u8, &Bad)) {} fn vals(_: Bad) -> Bad { - Bad::default() + Bad } } @@ -70,7 +70,7 @@ impl SelfTrait for Good { fn nested(_p1: Box, _p2: (&u8, &Self)) {} fn vals(_: Self) -> Self { - Self::default() + Self } } diff --git a/tests/ui/use_self_trait.stderr b/tests/ui/use_self_trait.stderr index 090729b9c3d5..6257f802dd80 100644 --- a/tests/ui/use_self_trait.stderr +++ b/tests/ui/use_self_trait.stderr @@ -63,7 +63,7 @@ LL | fn vals(_: Bad) -> Bad { error: unnecessary structure name repetition --> $DIR/use_self_trait.rs:36:9 | -LL | Bad::default() +LL | Bad | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition diff --git a/tests/ui/used_underscore_binding.rs b/tests/ui/used_underscore_binding.rs index 8c29e15b1459..2ad2b5a99d10 100644 --- a/tests/ui/used_underscore_binding.rs +++ b/tests/ui/used_underscore_binding.rs @@ -1,4 +1,8 @@ -// aux-build:proc_macro_derive.rs +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![feature(rustc_private)] #![warn(clippy::all)] #![warn(clippy::used_underscore_binding)] diff --git a/tests/ui/useless_asref.fixed b/tests/ui/useless_asref.fixed index 38e4b9201e6d..e42731f9bcf6 100644 --- a/tests/ui/useless_asref.fixed +++ b/tests/ui/useless_asref.fixed @@ -1,6 +1,10 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::useless_asref)] -#![allow(clippy::explicit_auto_deref, clippy::uninlined_format_args)] +#![allow( + clippy::explicit_auto_deref, + clippy::uninlined_format_args, + clippy::needless_pass_by_ref_mut +)] use std::fmt::Debug; diff --git a/tests/ui/useless_asref.rs b/tests/ui/useless_asref.rs index f1e83f9d396c..50c9990bb045 100644 --- a/tests/ui/useless_asref.rs +++ b/tests/ui/useless_asref.rs @@ -1,6 +1,10 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::useless_asref)] -#![allow(clippy::explicit_auto_deref, clippy::uninlined_format_args)] +#![allow( + clippy::explicit_auto_deref, + clippy::uninlined_format_args, + clippy::needless_pass_by_ref_mut +)] use std::fmt::Debug; diff --git a/tests/ui/useless_asref.stderr b/tests/ui/useless_asref.stderr index 67ce8b64e0e3..c97851ac6ea4 100644 --- a/tests/ui/useless_asref.stderr +++ b/tests/ui/useless_asref.stderr @@ -1,8 +1,8 @@ error: this call to `as_ref` does nothing - --> $DIR/useless_asref.rs:43:18 + --> $DIR/useless_asref.rs:47:18 | LL | foo_rstr(rstr.as_ref()); - | ^^^^^^^^^^^^^ help: try this: `rstr` + | ^^^^^^^^^^^^^ help: try: `rstr` | note: the lint level is defined here --> $DIR/useless_asref.rs:2:9 @@ -11,64 +11,64 @@ LL | #![deny(clippy::useless_asref)] | ^^^^^^^^^^^^^^^^^^^^^ error: this call to `as_ref` does nothing - --> $DIR/useless_asref.rs:45:20 + --> $DIR/useless_asref.rs:49:20 | LL | foo_rslice(rslice.as_ref()); - | ^^^^^^^^^^^^^^^ help: try this: `rslice` + | ^^^^^^^^^^^^^^^ help: try: `rslice` error: this call to `as_mut` does nothing - --> $DIR/useless_asref.rs:49:21 + --> $DIR/useless_asref.rs:53:21 | LL | foo_mrslice(mrslice.as_mut()); - | ^^^^^^^^^^^^^^^^ help: try this: `mrslice` + | ^^^^^^^^^^^^^^^^ help: try: `mrslice` error: this call to `as_ref` does nothing - --> $DIR/useless_asref.rs:51:20 + --> $DIR/useless_asref.rs:55:20 | LL | foo_rslice(mrslice.as_ref()); - | ^^^^^^^^^^^^^^^^ help: try this: `mrslice` + | ^^^^^^^^^^^^^^^^ help: try: `mrslice` error: this call to `as_ref` does nothing - --> $DIR/useless_asref.rs:58:20 + --> $DIR/useless_asref.rs:62:20 | LL | foo_rslice(rrrrrslice.as_ref()); - | ^^^^^^^^^^^^^^^^^^^ help: try this: `rrrrrslice` + | ^^^^^^^^^^^^^^^^^^^ help: try: `rrrrrslice` error: this call to `as_ref` does nothing - --> $DIR/useless_asref.rs:60:18 + --> $DIR/useless_asref.rs:64:18 | LL | foo_rstr(rrrrrstr.as_ref()); - | ^^^^^^^^^^^^^^^^^ help: try this: `rrrrrstr` + | ^^^^^^^^^^^^^^^^^ help: try: `rrrrrstr` error: this call to `as_mut` does nothing - --> $DIR/useless_asref.rs:65:21 + --> $DIR/useless_asref.rs:69:21 | LL | foo_mrslice(mrrrrrslice.as_mut()); - | ^^^^^^^^^^^^^^^^^^^^ help: try this: `mrrrrrslice` + | ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice` error: this call to `as_ref` does nothing - --> $DIR/useless_asref.rs:67:20 + --> $DIR/useless_asref.rs:71:20 | LL | foo_rslice(mrrrrrslice.as_ref()); - | ^^^^^^^^^^^^^^^^^^^^ help: try this: `mrrrrrslice` + | ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice` error: this call to `as_ref` does nothing - --> $DIR/useless_asref.rs:71:16 + --> $DIR/useless_asref.rs:75:16 | LL | foo_rrrrmr((&&&&MoreRef).as_ref()); - | ^^^^^^^^^^^^^^^^^^^^^^ help: try this: `(&&&&MoreRef)` + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&&&&MoreRef)` error: this call to `as_mut` does nothing - --> $DIR/useless_asref.rs:121:13 + --> $DIR/useless_asref.rs:125:13 | LL | foo_mrt(mrt.as_mut()); - | ^^^^^^^^^^^^ help: try this: `mrt` + | ^^^^^^^^^^^^ help: try: `mrt` error: this call to `as_ref` does nothing - --> $DIR/useless_asref.rs:123:12 + --> $DIR/useless_asref.rs:127:12 | LL | foo_rt(mrt.as_ref()); - | ^^^^^^^^^^^^ help: try this: `mrt` + | ^^^^^^^^^^^^ help: try: `mrt` error: aborting due to 11 previous errors diff --git a/tests/ui/useless_attribute.fixed b/tests/ui/useless_attribute.fixed index 871e4fb5c3a9..2ecf70103b0b 100644 --- a/tests/ui/useless_attribute.fixed +++ b/tests/ui/useless_attribute.fixed @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(unused)] #![warn(clippy::useless_attribute)] diff --git a/tests/ui/useless_attribute.rs b/tests/ui/useless_attribute.rs index cb50736ba395..67cf1f53e3a9 100644 --- a/tests/ui/useless_attribute.rs +++ b/tests/ui/useless_attribute.rs @@ -1,5 +1,9 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +<<<<<<< HEAD +//@aux-build:proc_macro_derive.rs:proc-macro +======= +//@aux-build:proc_macro_derive.rs +>>>>>>> e4f5d83fa (Fixed formatting.) #![allow(unused)] #![warn(clippy::useless_attribute)] diff --git a/tests/ui/useless_conversion.fixed b/tests/ui/useless_conversion.fixed index 94b206d8e58f..5d2c5b11658e 100644 --- a/tests/ui/useless_conversion.fixed +++ b/tests/ui/useless_conversion.fixed @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::useless_conversion)] -#![allow(clippy::unnecessary_wraps)] +#![allow(clippy::needless_if, clippy::unnecessary_wraps)] fn test_generic(val: T) -> T { let _ = val; @@ -33,6 +33,11 @@ fn test_issue_3913() -> Result<(), std::io::Error> { Ok(()) } +fn dont_lint_on_type_alias() { + type A = i32; + _ = A::from(0i32); +} + fn dont_lint_into_iter_on_immutable_local_implementing_iterator_in_expr() { let text = "foo\r\nbar\n\nbaz\n"; let lines = text.lines(); @@ -106,6 +111,7 @@ fn main() { test_questionmark().unwrap(); test_issue_3913().unwrap(); + dont_lint_on_type_alias(); dont_lint_into_iter_on_immutable_local_implementing_iterator_in_expr(); lint_into_iter_on_mutable_local_implementing_iterator_in_expr(); lint_into_iter_on_expr_implementing_iterator(); @@ -149,6 +155,35 @@ fn main() { let _ = vec![s4, s4, s4].into_iter(); } +#[allow(dead_code)] +fn explicit_into_iter_fn_arg() { + fn a(_: T) {} + fn b>(_: T) {} + fn c(_: impl IntoIterator) {} + fn d(_: T) + where + T: IntoIterator, + { + } + fn f(_: std::vec::IntoIter) {} + + a(vec![1, 2].into_iter()); + b(vec![1, 2]); + c(vec![1, 2]); + d(vec![1, 2]); + b([&1, &2, &3].into_iter().cloned()); + + b(vec![1, 2]); + b(vec![1, 2]); + + macro_rules! macro_generated { + () => { + vec![1, 2].into_iter() + }; + } + b(macro_generated!()); +} + #[derive(Copy, Clone)] struct Foo; diff --git a/tests/ui/useless_conversion.rs b/tests/ui/useless_conversion.rs index c7ae927941bf..03a3e3f95ba4 100644 --- a/tests/ui/useless_conversion.rs +++ b/tests/ui/useless_conversion.rs @@ -1,7 +1,7 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::useless_conversion)] -#![allow(clippy::unnecessary_wraps)] +#![allow(clippy::needless_if, clippy::unnecessary_wraps)] fn test_generic(val: T) -> T { let _ = T::from(val); @@ -33,6 +33,11 @@ fn test_issue_3913() -> Result<(), std::io::Error> { Ok(()) } +fn dont_lint_on_type_alias() { + type A = i32; + _ = A::from(0i32); +} + fn dont_lint_into_iter_on_immutable_local_implementing_iterator_in_expr() { let text = "foo\r\nbar\n\nbaz\n"; let lines = text.lines(); @@ -106,6 +111,7 @@ fn main() { test_questionmark().unwrap(); test_issue_3913().unwrap(); + dont_lint_on_type_alias(); dont_lint_into_iter_on_immutable_local_implementing_iterator_in_expr(); lint_into_iter_on_mutable_local_implementing_iterator_in_expr(); lint_into_iter_on_expr_implementing_iterator(); @@ -149,6 +155,35 @@ fn main() { let _ = vec![s4, s4, s4].into_iter().into_iter(); } +#[allow(dead_code)] +fn explicit_into_iter_fn_arg() { + fn a(_: T) {} + fn b>(_: T) {} + fn c(_: impl IntoIterator) {} + fn d(_: T) + where + T: IntoIterator, + { + } + fn f(_: std::vec::IntoIter) {} + + a(vec![1, 2].into_iter()); + b(vec![1, 2].into_iter()); + c(vec![1, 2].into_iter()); + d(vec![1, 2].into_iter()); + b([&1, &2, &3].into_iter().cloned()); + + b(vec![1, 2].into_iter().into_iter()); + b(vec![1, 2].into_iter().into_iter().into_iter()); + + macro_rules! macro_generated { + () => { + vec![1, 2].into_iter() + }; + } + b(macro_generated!()); +} + #[derive(Copy, Clone)] struct Foo; diff --git a/tests/ui/useless_conversion.stderr b/tests/ui/useless_conversion.stderr index be067c6843ac..040c4b1e48d7 100644 --- a/tests/ui/useless_conversion.stderr +++ b/tests/ui/useless_conversion.stderr @@ -23,100 +23,200 @@ LL | let _: i32 = 0i32.into(); | ^^^^^^^^^^^ help: consider removing `.into()`: `0i32` error: useless conversion to the same type: `std::str::Lines<'_>` - --> $DIR/useless_conversion.rs:45:22 + --> $DIR/useless_conversion.rs:50:22 | LL | if Some("ok") == lines.into_iter().next() {} | ^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `lines` error: useless conversion to the same type: `std::str::Lines<'_>` - --> $DIR/useless_conversion.rs:50:21 + --> $DIR/useless_conversion.rs:55:21 | LL | let mut lines = text.lines().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()` error: useless conversion to the same type: `std::str::Lines<'_>` - --> $DIR/useless_conversion.rs:56:22 + --> $DIR/useless_conversion.rs:61:22 | LL | if Some("ok") == text.lines().into_iter().next() {} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()` error: useless conversion to the same type: `std::ops::Range` - --> $DIR/useless_conversion.rs:62:13 + --> $DIR/useless_conversion.rs:67:13 | LL | let _ = NUMBERS.into_iter().next(); | ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS` error: useless conversion to the same type: `std::ops::Range` - --> $DIR/useless_conversion.rs:67:17 + --> $DIR/useless_conversion.rs:72:17 | LL | let mut n = NUMBERS.into_iter(); | ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion.rs:128:21 + --> $DIR/useless_conversion.rs:134:21 | LL | let _: String = "foo".to_string().into(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion.rs:129:21 + --> $DIR/useless_conversion.rs:135:21 | LL | let _: String = From::from("foo".to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion.rs:130:13 + --> $DIR/useless_conversion.rs:136:13 | LL | let _ = String::from("foo".to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion.rs:131:13 + --> $DIR/useless_conversion.rs:137:13 | LL | let _ = String::from(format!("A: {:04}", 123)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!("A: {:04}", 123)` error: useless conversion to the same type: `std::str::Lines<'_>` - --> $DIR/useless_conversion.rs:132:13 + --> $DIR/useless_conversion.rs:138:13 | LL | let _ = "".lines().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `"".lines()` error: useless conversion to the same type: `std::vec::IntoIter` - --> $DIR/useless_conversion.rs:133:13 + --> $DIR/useless_conversion.rs:139:13 | LL | let _ = vec![1, 2, 3].into_iter().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion.rs:134:21 + --> $DIR/useless_conversion.rs:140:21 | LL | let _: String = format!("Hello {}", "world").into(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")` error: useless conversion to the same type: `i32` - --> $DIR/useless_conversion.rs:139:13 + --> $DIR/useless_conversion.rs:145:13 | LL | let _ = i32::from(a + b) * 3; | ^^^^^^^^^^^^^^^^ help: consider removing `i32::from()`: `(a + b)` error: useless conversion to the same type: `Foo<'a'>` - --> $DIR/useless_conversion.rs:145:23 + --> $DIR/useless_conversion.rs:151:23 | LL | let _: Foo<'a'> = s2.into(); | ^^^^^^^^^ help: consider removing `.into()`: `s2` error: useless conversion to the same type: `Foo<'a'>` - --> $DIR/useless_conversion.rs:147:13 + --> $DIR/useless_conversion.rs:153:13 | LL | let _ = Foo::<'a'>::from(s3); | ^^^^^^^^^^^^^^^^^^^^ help: consider removing `Foo::<'a'>::from()`: `s3` error: useless conversion to the same type: `std::vec::IntoIter>` - --> $DIR/useless_conversion.rs:149:13 + --> $DIR/useless_conversion.rs:155:13 | LL | let _ = vec![s4, s4, s4].into_iter().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()` -error: aborting due to 19 previous errors +error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` + --> $DIR/useless_conversion.rs:171:7 + | +LL | b(vec![1, 2].into_iter()); +<<<<<<< HEAD +<<<<<<< HEAD + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` +======= + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2]` +>>>>>>> de1f41001 (merge `explicit_into_iter_fn_arg` into `useless_conversion`) +======= + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` +>>>>>>> 5a7e33e5b (add plural form to useless_conversion if depth > 0) + | +note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` + --> $DIR/useless_conversion.rs:161:13 + | +LL | fn b>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` + --> $DIR/useless_conversion.rs:172:7 + | +LL | c(vec![1, 2].into_iter()); +<<<<<<< HEAD +<<<<<<< HEAD + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` +======= + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2]` +>>>>>>> de1f41001 (merge `explicit_into_iter_fn_arg` into `useless_conversion`) +======= + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` +>>>>>>> 5a7e33e5b (add plural form to useless_conversion if depth > 0) + | +note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` + --> $DIR/useless_conversion.rs:162:18 + | +LL | fn c(_: impl IntoIterator) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` + --> $DIR/useless_conversion.rs:173:7 + | +LL | d(vec![1, 2].into_iter()); +<<<<<<< HEAD +<<<<<<< HEAD + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` +======= + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2]` +>>>>>>> de1f41001 (merge `explicit_into_iter_fn_arg` into `useless_conversion`) +======= + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` +>>>>>>> 5a7e33e5b (add plural form to useless_conversion if depth > 0) + | +note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` + --> $DIR/useless_conversion.rs:165:12 + | +LL | T: IntoIterator, + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` + --> $DIR/useless_conversion.rs:176:7 + | +LL | b(vec![1, 2].into_iter().into_iter()); +<<<<<<< HEAD +<<<<<<< HEAD + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]` +======= + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2]` +>>>>>>> de1f41001 (merge `explicit_into_iter_fn_arg` into `useless_conversion`) +======= + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]` +>>>>>>> 5a7e33e5b (add plural form to useless_conversion if depth > 0) + | +note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` + --> $DIR/useless_conversion.rs:161:13 + | +LL | fn b>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` + --> $DIR/useless_conversion.rs:177:7 + | +LL | b(vec![1, 2].into_iter().into_iter().into_iter()); +<<<<<<< HEAD +<<<<<<< HEAD + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]` +======= + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2]` +>>>>>>> de1f41001 (merge `explicit_into_iter_fn_arg` into `useless_conversion`) +======= + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]` +>>>>>>> 5a7e33e5b (add plural form to useless_conversion if depth > 0) + | +note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` + --> $DIR/useless_conversion.rs:161:13 + | +LL | fn b>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 24 previous errors diff --git a/tests/ui/useless_conversion_try.rs b/tests/ui/useless_conversion_try.rs index 4acf5b5fa2d1..ec0512ce210b 100644 --- a/tests/ui/useless_conversion_try.rs +++ b/tests/ui/useless_conversion_try.rs @@ -1,4 +1,5 @@ #![deny(clippy::useless_conversion)] +#![allow(clippy::needless_if)] fn test_generic(val: T) -> T { let _ = T::try_from(val).unwrap(); diff --git a/tests/ui/useless_conversion_try.stderr b/tests/ui/useless_conversion_try.stderr index 9aef9dda6f68..54189f8d2860 100644 --- a/tests/ui/useless_conversion_try.stderr +++ b/tests/ui/useless_conversion_try.stderr @@ -1,5 +1,5 @@ error: useless conversion to the same type: `T` - --> $DIR/useless_conversion_try.rs:4:13 + --> $DIR/useless_conversion_try.rs:5:13 | LL | let _ = T::try_from(val).unwrap(); | ^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(clippy::useless_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: useless conversion to the same type: `T` - --> $DIR/useless_conversion_try.rs:5:5 + --> $DIR/useless_conversion_try.rs:6:5 | LL | val.try_into().unwrap() | ^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | val.try_into().unwrap() = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:27:21 + --> $DIR/useless_conversion_try.rs:28:21 | LL | let _: String = "foo".to_string().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | let _: String = "foo".to_string().try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:28:21 + --> $DIR/useless_conversion_try.rs:29:21 | LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap(); = help: consider removing `TryFrom::try_from()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:29:13 + --> $DIR/useless_conversion_try.rs:30:13 | LL | let _ = String::try_from("foo".to_string()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | let _ = String::try_from("foo".to_string()).unwrap(); = help: consider removing `String::try_from()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:30:13 + --> $DIR/useless_conversion_try.rs:31:13 | LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); = help: consider removing `String::try_from()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:31:21 + --> $DIR/useless_conversion_try.rs:32:21 | LL | let _: String = format!("Hello {}", "world").try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | let _: String = format!("Hello {}", "world").try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:32:21 + --> $DIR/useless_conversion_try.rs:33:21 | LL | let _: String = String::new().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | let _: String = String::new().try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> $DIR/useless_conversion_try.rs:33:27 + --> $DIR/useless_conversion_try.rs:34:27 | LL | let _: String = match String::from("_").try_into() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/vec.fixed b/tests/ui/vec.fixed index 2518d8049150..5b3f06d51fa5 100644 --- a/tests/ui/vec.fixed +++ b/tests/ui/vec.fixed @@ -1,10 +1,22 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::useless_vec)] -#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args)] +#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)] +use std::rc::Rc; + +struct StructWithVec { + _x: Vec, +} +<<<<<<< HEAD +======= + +<<<<<<< HEAD #[derive(Debug)] struct NonCopy; +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) fn on_slice(_: &[u8]) {} fn on_mut_slice(_: &mut [u8]) {} @@ -60,14 +72,6 @@ fn main() { on_mut_slice(&mut vec![2; line.length]); on_mut_slice(&mut vec![2; line.length()]); - for a in &[1, 2, 3] { - println!("{:?}", a); - } - - for a in vec![NonCopy, NonCopy] { - println!("{:?}", a); - } - on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` @@ -75,4 +79,151 @@ fn main() { for a in vec![1; 201] { println!("{:?}", a); } + +<<<<<<< HEAD +<<<<<<< HEAD + // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 + let _x: i32 = [1, 2, 3].iter().sum(); + +======= +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 + let _x: i32 = [1, 2, 3].iter().sum(); + +>>>>>>> 50ba45998 (add- and fix existing tests) + // Do lint + let mut x = [1, 2, 3]; + x.fill(123); + dbg!(x[0]); + dbg!(x.len()); + dbg!(x.iter().sum::()); + + let _x: &[i32] = &[1, 2, 3]; + +<<<<<<< HEAD +<<<<<<< HEAD + for _ in [1, 2, 3] {} +======= + for _ in &[1, 2, 3] {} +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + for _ in [1, 2, 3] {} +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) + + // Don't lint + let x = vec![1, 2, 3]; + let _v: Vec = x; + + let x = vec![1, 2, 3]; + let _s = StructWithVec { _x: x }; + + // Explicit type annotation would make the change to [1, 2, 3] + // a compile error. + let _x: Vec = vec![1, 2, 3]; + + // Calling a Vec method through a mutable reference + let mut x = vec![1, 2, 3]; + let re = &mut x; + re.push(4); + + // Comparing arrays whose length is not equal is a compile error + let x = vec![1, 2, 3]; + let y = vec![1, 2, 3, 4]; + dbg!(x == y); + + // Non-copy types + let _x = vec![String::new(); 10]; + #[allow(clippy::rc_clone_in_vec_init)] + let _x = vec![Rc::new(1); 10]; + + // Too large + let _x = vec![1; 201]; +<<<<<<< HEAD +} + +#[clippy::msrv = "1.53"] +fn above() { + for a in [1, 2, 3] { + let _: usize = a; + } + + for a in [String::new(), String::new()] { + let _: String = a; + } +} + +#[clippy::msrv = "1.52"] +fn below() { + for a in vec![1, 2, 3] { + let _: usize = a; + } + + for a in vec![String::new(), String::new()] { + let _: String = a; + } +======= +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +} + +fn issue11075() { + macro_rules! repro { + ($e:expr) => { + stringify!($e) + }; + } + for _string in [repro!(true), repro!(null)] { + unimplemented!(); + } + + macro_rules! in_macro { + ($e:expr, $vec:expr, $vec2:expr) => {{ + vec![1; 2].fill(3); + vec![1, 2].fill(3); + for _ in vec![1, 2] {} + for _ in vec![1; 2] {} + for _ in vec![$e, $e] {} + for _ in vec![$e; 2] {} + for _ in $vec {} + for _ in $vec2 {} + }}; + } + + in_macro!(1, [1, 2], [1; 2]); + + macro_rules! from_macro { + () => { + vec![1, 2, 3] + }; + } + macro_rules! from_macro_repeat { + () => { + vec![1; 3] + }; + } + + for _ in from_macro!() {} + for _ in from_macro_repeat!() {} +} + +#[clippy::msrv = "1.53"] +fn above() { + for a in [1, 2, 3] { + let _: usize = a; + } + + for a in [String::new(), String::new()] { + let _: String = a; + } +} + +#[clippy::msrv = "1.52"] +fn below() { + for a in vec![1, 2, 3] { + let _: usize = a; + } + + for a in vec![String::new(), String::new()] { + let _: String = a; + } } diff --git a/tests/ui/vec.rs b/tests/ui/vec.rs index e1492e2f3aef..9065452d2182 100644 --- a/tests/ui/vec.rs +++ b/tests/ui/vec.rs @@ -1,10 +1,22 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::useless_vec)] -#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args)] +#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)] +use std::rc::Rc; + +struct StructWithVec { + _x: Vec, +} +<<<<<<< HEAD +======= + +<<<<<<< HEAD #[derive(Debug)] struct NonCopy; +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) fn on_slice(_: &[u8]) {} fn on_mut_slice(_: &mut [u8]) {} @@ -60,14 +72,6 @@ fn main() { on_mut_slice(&mut vec![2; line.length]); on_mut_slice(&mut vec![2; line.length()]); - for a in vec![1, 2, 3] { - println!("{:?}", a); - } - - for a in vec![NonCopy, NonCopy] { - println!("{:?}", a); - } - on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` @@ -75,4 +79,143 @@ fn main() { for a in vec![1; 201] { println!("{:?}", a); } + +<<<<<<< HEAD +<<<<<<< HEAD + // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 + let _x: i32 = vec![1, 2, 3].iter().sum(); + +======= +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 + let _x: i32 = vec![1, 2, 3].iter().sum(); + +>>>>>>> 50ba45998 (add- and fix existing tests) + // Do lint + let mut x = vec![1, 2, 3]; + x.fill(123); + dbg!(x[0]); + dbg!(x.len()); + dbg!(x.iter().sum::()); + + let _x: &[i32] = &vec![1, 2, 3]; + + for _ in vec![1, 2, 3] {} + + // Don't lint + let x = vec![1, 2, 3]; + let _v: Vec = x; + + let x = vec![1, 2, 3]; + let _s = StructWithVec { _x: x }; + + // Explicit type annotation would make the change to [1, 2, 3] + // a compile error. + let _x: Vec = vec![1, 2, 3]; + + // Calling a Vec method through a mutable reference + let mut x = vec![1, 2, 3]; + let re = &mut x; + re.push(4); + + // Comparing arrays whose length is not equal is a compile error + let x = vec![1, 2, 3]; + let y = vec![1, 2, 3, 4]; + dbg!(x == y); + + // Non-copy types + let _x = vec![String::new(); 10]; + #[allow(clippy::rc_clone_in_vec_init)] + let _x = vec![Rc::new(1); 10]; + + // Too large + let _x = vec![1; 201]; +<<<<<<< HEAD +} + +#[clippy::msrv = "1.53"] +fn above() { + for a in vec![1, 2, 3] { + let _: usize = a; + } + + for a in vec![String::new(), String::new()] { + let _: String = a; + } +} + +#[clippy::msrv = "1.52"] +fn below() { + for a in vec![1, 2, 3] { + let _: usize = a; + } + + for a in vec![String::new(), String::new()] { + let _: String = a; + } +======= +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +} + +fn issue11075() { + macro_rules! repro { + ($e:expr) => { + stringify!($e) + }; + } + for _string in vec![repro!(true), repro!(null)] { + unimplemented!(); + } + + macro_rules! in_macro { + ($e:expr, $vec:expr, $vec2:expr) => {{ + vec![1; 2].fill(3); + vec![1, 2].fill(3); + for _ in vec![1, 2] {} + for _ in vec![1; 2] {} + for _ in vec![$e, $e] {} + for _ in vec![$e; 2] {} + for _ in $vec {} + for _ in $vec2 {} + }}; + } + + in_macro!(1, vec![1, 2], vec![1; 2]); + + macro_rules! from_macro { + () => { + vec![1, 2, 3] + }; + } + macro_rules! from_macro_repeat { + () => { + vec![1; 3] + }; + } + + for _ in from_macro!() {} + for _ in from_macro_repeat!() {} +} + +#[clippy::msrv = "1.53"] +fn above() { + for a in vec![1, 2, 3] { + let _: usize = a; + } + + for a in vec![String::new(), String::new()] { + let _: String = a; + } +} + +#[clippy::msrv = "1.52"] +fn below() { + for a in vec![1, 2, 3] { + let _: usize = a; + } + + for a in vec![String::new(), String::new()] { + let _: String = a; + } } diff --git a/tests/ui/vec.stderr b/tests/ui/vec.stderr index 7d1de05a5c83..0743be053f03 100644 --- a/tests/ui/vec.stderr +++ b/tests/ui/vec.stderr @@ -1,5 +1,13 @@ error: useless use of `vec!` - --> $DIR/vec.rs:28:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/vec.rs:31:14 +======= + --> $DIR/vec.rs:34:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/vec.rs:31:14 +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) | LL | on_slice(&vec![]); | ^^^^^^^ help: you can use a slice directly: `&[]` @@ -7,64 +15,255 @@ LL | on_slice(&vec![]); = note: `-D clippy::useless-vec` implied by `-D warnings` error: useless use of `vec!` - --> $DIR/vec.rs:30:18 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/vec.rs:33:18 +======= + --> $DIR/vec.rs:36:18 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/vec.rs:33:18 +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) | LL | on_mut_slice(&mut vec![]); | ^^^^^^^^^^^ help: you can use a slice directly: `&mut []` error: useless use of `vec!` - --> $DIR/vec.rs:32:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/vec.rs:35:14 +======= + --> $DIR/vec.rs:38:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/vec.rs:35:14 +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) | LL | on_slice(&vec![1, 2]); | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` error: useless use of `vec!` - --> $DIR/vec.rs:34:18 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/vec.rs:37:18 +======= + --> $DIR/vec.rs:40:18 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/vec.rs:37:18 +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) | LL | on_mut_slice(&mut vec![1, 2]); | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` error: useless use of `vec!` - --> $DIR/vec.rs:36:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/vec.rs:39:14 +======= + --> $DIR/vec.rs:42:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/vec.rs:39:14 +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) | LL | on_slice(&vec![1, 2]); | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` error: useless use of `vec!` - --> $DIR/vec.rs:38:18 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/vec.rs:41:18 +======= + --> $DIR/vec.rs:44:18 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/vec.rs:41:18 +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) | LL | on_mut_slice(&mut vec![1, 2]); | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` error: useless use of `vec!` - --> $DIR/vec.rs:40:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/vec.rs:43:14 +======= + --> $DIR/vec.rs:46:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/vec.rs:43:14 +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) | LL | on_slice(&vec!(1, 2)); | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` error: useless use of `vec!` - --> $DIR/vec.rs:42:18 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/vec.rs:45:18 +======= + --> $DIR/vec.rs:48:18 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/vec.rs:45:18 +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) | LL | on_mut_slice(&mut vec![1, 2]); | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` error: useless use of `vec!` - --> $DIR/vec.rs:44:14 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/vec.rs:47:14 +======= + --> $DIR/vec.rs:50:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/vec.rs:47:14 +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) | LL | on_slice(&vec![1; 2]); | ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]` error: useless use of `vec!` - --> $DIR/vec.rs:46:18 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/vec.rs:49:18 +======= + --> $DIR/vec.rs:52:18 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/vec.rs:49:18 +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) | LL | on_mut_slice(&mut vec![1; 2]); | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]` error: useless use of `vec!` - --> $DIR/vec.rs:63:14 +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 50ba45998 (add- and fix existing tests) + --> $DIR/vec.rs:75:19 + | +LL | let _x: i32 = vec![1, 2, 3].iter().sum(); + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> $DIR/vec.rs:78:17 +<<<<<<< HEAD + | +LL | let mut x = vec![1, 2, 3]; + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> $DIR/vec.rs:84:22 + | +LL | let _x: &[i32] = &vec![1, 2, 3]; + | ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]` + +error: useless use of `vec!` + --> $DIR/vec.rs:86:14 + | +LL | for _ in vec![1, 2, 3] {} + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` +<<<<<<< HEAD + --> $DIR/vec.rs:120:14 +======= + --> $DIR/vec.rs:69:14 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) | LL | for a in vec![1, 2, 3] { - | ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]` + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` +<<<<<<< HEAD + --> $DIR/vec.rs:124:14 + | +LL | for a in vec![String::new(), String::new()] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]` + +error: aborting due to 16 previous errors +======= + --> $DIR/vec.rs:86:17 +======= + --> $DIR/vec.rs:75:17 +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) +======= +>>>>>>> 50ba45998 (add- and fix existing tests) + | +LL | let mut x = vec![1, 2, 3]; + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> $DIR/vec.rs:84:22 + | +LL | let _x: &[i32] = &vec![1, 2, 3]; + | ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]` + +error: useless use of `vec!` + --> $DIR/vec.rs:86:14 + | +LL | for _ in vec![1, 2, 3] {} + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +<<<<<<< HEAD +error: aborting due to 14 previous errors +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= +error: useless use of `vec!` + --> $DIR/vec.rs:120:14 +======= + --> $DIR/vec.rs:124:20 + | +LL | for _string in vec![repro!(true), repro!(null)] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[repro!(true), repro!(null)]` + +error: useless use of `vec!` +<<<<<<< HEAD + --> $DIR/vec.rs:131:14 +>>>>>>> 1f77f8cc3 ([`useless_vec`]: use the source span) +======= + --> $DIR/vec.rs:141:18 + | +LL | in_macro!(1, vec![1, 2], vec![1; 2]); + | ^^^^^^^^^^ help: you can use an array directly: `[1, 2]` + +error: useless use of `vec!` + --> $DIR/vec.rs:141:30 + | +LL | in_macro!(1, vec![1, 2], vec![1; 2]); + | ^^^^^^^^^^ help: you can use an array directly: `[1; 2]` + +error: useless use of `vec!` + --> $DIR/vec.rs:160:14 +>>>>>>> b4549c50b ([`useless_vec`]: add more tests for macro combinations) + | +LL | for a in vec![1, 2, 3] { + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> $DIR/vec.rs:164:14 + | +LL | for a in vec![String::new(), String::new()] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]` -error: aborting due to 11 previous errors +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +error: aborting due to 15 previous errors +>>>>>>> 96697d2ee (Fix `useless_vec` suggestion in `for _ in vec![..]`) +======= +error: aborting due to 16 previous errors +>>>>>>> 50ba45998 (add- and fix existing tests) +======= +error: aborting due to 17 previous errors +>>>>>>> 1f77f8cc3 ([`useless_vec`]: use the source span) +======= +error: aborting due to 19 previous errors +>>>>>>> b4549c50b ([`useless_vec`]: add more tests for macro combinations) diff --git a/tests/ui/vec_box_sized.fixed b/tests/ui/vec_box_sized.fixed index a40d91fdb18a..0d0f710b558b 100644 --- a/tests/ui/vec_box_sized.fixed +++ b/tests/ui/vec_box_sized.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] diff --git a/tests/ui/vec_box_sized.rs b/tests/ui/vec_box_sized.rs index 843bbb64e719..fd3a7543ee1a 100644 --- a/tests/ui/vec_box_sized.rs +++ b/tests/ui/vec_box_sized.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] diff --git a/tests/ui/vtable_address_comparisons.rs b/tests/ui/vtable_address_comparisons.rs index a9a4a0f5a6b5..99c3f468f04a 100644 --- a/tests/ui/vtable_address_comparisons.rs +++ b/tests/ui/vtable_address_comparisons.rs @@ -23,12 +23,6 @@ fn main() { let b = &1 as &dyn Debug; ptr::eq(a, b); - let a: Rc = Rc::new(1); - Rc::ptr_eq(&a, &a); - - let a: Arc = Arc::new(1); - Arc::ptr_eq(&a, &a); - // These should be fine: let a = &1; ptr::eq(a, a); @@ -39,6 +33,12 @@ fn main() { let a = Arc::new(1); Arc::ptr_eq(&a, &a); + let a: Rc = Rc::new(1); + Rc::ptr_eq(&a, &a); + + let a: Arc = Arc::new(1); + Arc::ptr_eq(&a, &a); + let a: &[u8] = b""; ptr::eq(a, a); } diff --git a/tests/ui/vtable_address_comparisons.stderr b/tests/ui/vtable_address_comparisons.stderr index 14748f583f0c..7b866d274d58 100644 --- a/tests/ui/vtable_address_comparisons.stderr +++ b/tests/ui/vtable_address_comparisons.stderr @@ -63,21 +63,5 @@ LL | ptr::eq(a, b); | = help: consider extracting and comparing data pointers only -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:27:5 - | -LL | Rc::ptr_eq(&a, &a); - | ^^^^^^^^^^^^^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:30:5 - | -LL | Arc::ptr_eq(&a, &a); - | ^^^^^^^^^^^^^^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: aborting due to 10 previous errors +error: aborting due to 8 previous errors diff --git a/tests/ui/while_let_on_iterator.fixed b/tests/ui/while_let_on_iterator.fixed index 5afa0a89f82c..7de3f16bb3ed 100644 --- a/tests/ui/while_let_on_iterator.fixed +++ b/tests/ui/while_let_on_iterator.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::while_let_on_iterator)] #![allow(dead_code, unreachable_code, unused_mut)] #![allow( @@ -6,7 +6,16 @@ clippy::manual_find, clippy::never_loop, clippy::redundant_closure_call, - clippy::uninlined_format_args +<<<<<<< HEAD +<<<<<<< HEAD + clippy::single_range_in_vec_init, +======= +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + clippy::single_range_in_vec_init, +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) + clippy::uninlined_format_args, + clippy::useless_vec )] fn base() { diff --git a/tests/ui/while_let_on_iterator.rs b/tests/ui/while_let_on_iterator.rs index 3de586c9d8fd..5feafda1b8bd 100644 --- a/tests/ui/while_let_on_iterator.rs +++ b/tests/ui/while_let_on_iterator.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::while_let_on_iterator)] #![allow(dead_code, unreachable_code, unused_mut)] #![allow( @@ -6,7 +6,16 @@ clippy::manual_find, clippy::never_loop, clippy::redundant_closure_call, - clippy::uninlined_format_args +<<<<<<< HEAD +<<<<<<< HEAD + clippy::single_range_in_vec_init, +======= +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + clippy::single_range_in_vec_init, +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) + clippy::uninlined_format_args, + clippy::useless_vec )] fn base() { diff --git a/tests/ui/while_let_on_iterator.stderr b/tests/ui/while_let_on_iterator.stderr index 4d98666190d6..a6ebc5092c7c 100644 --- a/tests/ui/while_let_on_iterator.stderr +++ b/tests/ui/while_let_on_iterator.stderr @@ -1,5 +1,13 @@ error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:14:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:16:5 +======= + --> $DIR/while_let_on_iterator.rs:15:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:16:5 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Option::Some(x) = iter.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in iter` @@ -7,151 +15,351 @@ LL | while let Option::Some(x) = iter.next() { = note: `-D clippy::while-let-on-iterator` implied by `-D warnings` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:19:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:21:5 +======= + --> $DIR/while_let_on_iterator.rs:20:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:21:5 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(x) = iter.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in iter` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:24:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:26:5 +======= + --> $DIR/while_let_on_iterator.rs:25:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:26:5 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(_) = iter.next() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in iter` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:100:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:102:9 +======= + --> $DIR/while_let_on_iterator.rs:101:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:102:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some([..]) = it.next() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for [..] in it` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:107:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:109:9 +======= + --> $DIR/while_let_on_iterator.rs:108:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:109:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some([_x]) = it.next() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for [_x] in it` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:120:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:122:9 +======= + --> $DIR/while_let_on_iterator.rs:121:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:122:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(x @ [_]) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x @ [_] in it` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:140:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:142:9 +======= + --> $DIR/while_let_on_iterator.rs:141:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:142:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(_) = y.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in y` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:197:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:199:9 +======= + --> $DIR/while_let_on_iterator.rs:198:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:199:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(m) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:208:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:210:5 +======= + --> $DIR/while_let_on_iterator.rs:209:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:210:5 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(n) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in it` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:210:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:212:9 +======= + --> $DIR/while_let_on_iterator.rs:211:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:212:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(m) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:219:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:221:9 +======= + --> $DIR/while_let_on_iterator.rs:220:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:221:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(m) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:228:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:230:9 +======= + --> $DIR/while_let_on_iterator.rs:229:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:230:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(m) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:245:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:247:9 +======= + --> $DIR/while_let_on_iterator.rs:246:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:247:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(m) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:260:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:262:13 +======= + --> $DIR/while_let_on_iterator.rs:261:13 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:262:13 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(i) = self.0.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for i in self.0.by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:292:13 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:294:13 +======= + --> $DIR/while_let_on_iterator.rs:293:13 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:294:13 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(i) = self.0.0.0.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for i in self.0.0.0.by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:321:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:323:5 +======= + --> $DIR/while_let_on_iterator.rs:322:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:323:5 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(n) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in it.by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:333:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:335:9 +======= + --> $DIR/while_let_on_iterator.rs:334:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:335:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:347:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:349:5 +======= + --> $DIR/while_let_on_iterator.rs:348:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:349:5 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:358:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:360:5 +======= + --> $DIR/while_let_on_iterator.rs:359:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:360:5 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(x) = it.0.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.0.by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:393:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:395:5 +======= + --> $DIR/while_let_on_iterator.rs:394:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:395:5 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(x) = s.x.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in s.x.by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:400:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:402:5 +======= + --> $DIR/while_let_on_iterator.rs:401:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:402:5 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(x) = x[0].next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in x[0].by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:408:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:410:9 +======= + --> $DIR/while_let_on_iterator.rs:409:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:410:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:418:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:420:9 +======= + --> $DIR/while_let_on_iterator.rs:419:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:420:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:428:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:430:9 +======= + --> $DIR/while_let_on_iterator.rs:429:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:430:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:438:9 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:440:9 +======= + --> $DIR/while_let_on_iterator.rs:439:9 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:440:9 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(x) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it` error: this loop could be written as a `for` loop - --> $DIR/while_let_on_iterator.rs:448:5 +<<<<<<< HEAD +<<<<<<< HEAD + --> $DIR/while_let_on_iterator.rs:450:5 +======= + --> $DIR/while_let_on_iterator.rs:449:5 +>>>>>>> 05f78e530 (allow the lint in a bunch of tests) +======= + --> $DIR/while_let_on_iterator.rs:450:5 +>>>>>>> 6702c7a7a (Add lint [`single_range_in_vec_init`]) | LL | while let Some(..) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it` diff --git a/tests/ui/wildcard_enum_match_arm.fixed b/tests/ui/wildcard_enum_match_arm.fixed index 293bf75a7176..ccb40acfbe1b 100644 --- a/tests/ui/wildcard_enum_match_arm.fixed +++ b/tests/ui/wildcard_enum_match_arm.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:non-exhaustive-enum.rs +//@run-rustfix +//@aux-build:non-exhaustive-enum.rs #![deny(clippy::wildcard_enum_match_arm)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow( diff --git a/tests/ui/wildcard_enum_match_arm.rs b/tests/ui/wildcard_enum_match_arm.rs index decd86165f3a..3ce00b021a53 100644 --- a/tests/ui/wildcard_enum_match_arm.rs +++ b/tests/ui/wildcard_enum_match_arm.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:non-exhaustive-enum.rs +//@run-rustfix +//@aux-build:non-exhaustive-enum.rs #![deny(clippy::wildcard_enum_match_arm)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow( diff --git a/tests/ui/wildcard_enum_match_arm.stderr b/tests/ui/wildcard_enum_match_arm.stderr index 30d29aa4e77a..5b88ae4ab665 100644 --- a/tests/ui/wildcard_enum_match_arm.stderr +++ b/tests/ui/wildcard_enum_match_arm.stderr @@ -2,7 +2,7 @@ error: wildcard match will also match any future added variants --> $DIR/wildcard_enum_match_arm.rs:40:9 | LL | _ => eprintln!("Not red"), - | ^ help: try this: `Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan` + | ^ help: try: `Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan` | note: the lint level is defined here --> $DIR/wildcard_enum_match_arm.rs:3:9 @@ -14,31 +14,31 @@ error: wildcard match will also match any future added variants --> $DIR/wildcard_enum_match_arm.rs:44:9 | LL | _not_red => eprintln!("Not red"), - | ^^^^^^^^ help: try this: `_not_red @ Color::Green | _not_red @ Color::Blue | _not_red @ Color::Rgb(..) | _not_red @ Color::Cyan` + | ^^^^^^^^ help: try: `_not_red @ Color::Green | _not_red @ Color::Blue | _not_red @ Color::Rgb(..) | _not_red @ Color::Cyan` error: wildcard match will also match any future added variants --> $DIR/wildcard_enum_match_arm.rs:48:9 | LL | not_red => format!("{:?}", not_red), - | ^^^^^^^ help: try this: `not_red @ Color::Green | not_red @ Color::Blue | not_red @ Color::Rgb(..) | not_red @ Color::Cyan` + | ^^^^^^^ help: try: `not_red @ Color::Green | not_red @ Color::Blue | not_red @ Color::Rgb(..) | not_red @ Color::Cyan` error: wildcard match will also match any future added variants --> $DIR/wildcard_enum_match_arm.rs:64:9 | LL | _ => "No red", - | ^ help: try this: `Color::Red | Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan` + | ^ help: try: `Color::Red | Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan` error: wildcard matches known variants and will also match future added variants --> $DIR/wildcard_enum_match_arm.rs:81:9 | LL | _ => {}, - | ^ help: try this: `ErrorKind::PermissionDenied | _` + | ^ help: try: `ErrorKind::PermissionDenied | _` error: wildcard match will also match any future added variants --> $DIR/wildcard_enum_match_arm.rs:99:13 | LL | _ => (), - | ^ help: try this: `Enum::B | Enum::__Private` + | ^ help: try: `Enum::B | Enum::__Private` error: aborting due to 6 previous errors diff --git a/tests/ui/wildcard_imports.fixed b/tests/ui/wildcard_imports.fixed index 0baec6f0b641..67173f40654f 100644 --- a/tests/ui/wildcard_imports.fixed +++ b/tests/ui/wildcard_imports.fixed @@ -1,6 +1,6 @@ -// edition:2015 -// run-rustfix -// aux-build:wildcard_imports_helper.rs +//@edition:2015 +//@run-rustfix +//@aux-build:wildcard_imports_helper.rs // the 2015 edition here is needed because edition 2018 changed the module system // (see https://doc.rust-lang.org/edition-guide/rust-2018/path-changes.html) which means the lint @@ -24,6 +24,7 @@ use wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar; use wildcard_imports_helper::{ExternA, extern_foo}; use std::io::prelude::*; +use wildcard_imports_helper::extern_prelude::v1::*; use wildcard_imports_helper::prelude::v1::*; struct ReadFoo; @@ -81,6 +82,7 @@ fn main() { let _ = inner_struct_mod::C; let _ = ExternA; let _ = PreludeModAnywhere; + let _ = ExternPreludeModAnywhere; double_struct_import_test!(); double_struct_import_test!(); @@ -110,6 +112,7 @@ mod in_fn_test { } fn test_inner_nested() { + #[rustfmt::skip] use self::{inner::inner_foo, inner2::inner_bar}; inner_foo(); @@ -209,7 +212,7 @@ mod super_imports { } mod use_explicit_should_be_replaced { - use super_imports::foofoo; + use crate::super_imports::foofoo; fn with_explicit() { let _ = foofoo(); diff --git a/tests/ui/wildcard_imports.rs b/tests/ui/wildcard_imports.rs index db591d56ab4d..8223b6930181 100644 --- a/tests/ui/wildcard_imports.rs +++ b/tests/ui/wildcard_imports.rs @@ -1,6 +1,6 @@ -// edition:2015 -// run-rustfix -// aux-build:wildcard_imports_helper.rs +//@edition:2015 +//@run-rustfix +//@aux-build:wildcard_imports_helper.rs // the 2015 edition here is needed because edition 2018 changed the module system // (see https://doc.rust-lang.org/edition-guide/rust-2018/path-changes.html) which means the lint @@ -24,6 +24,7 @@ use wildcard_imports_helper::inner::inner_for_self_import::*; use wildcard_imports_helper::*; use std::io::prelude::*; +use wildcard_imports_helper::extern_prelude::v1::*; use wildcard_imports_helper::prelude::v1::*; struct ReadFoo; @@ -81,6 +82,7 @@ fn main() { let _ = inner_struct_mod::C; let _ = ExternA; let _ = PreludeModAnywhere; + let _ = ExternPreludeModAnywhere; double_struct_import_test!(); double_struct_import_test!(); @@ -110,6 +112,7 @@ mod in_fn_test { } fn test_inner_nested() { + #[rustfmt::skip] use self::{inner::*, inner2::*}; inner_foo(); @@ -210,7 +213,7 @@ mod super_imports { } mod use_explicit_should_be_replaced { - use super_imports::*; + use crate::super_imports::*; fn with_explicit() { let _ = foofoo(); diff --git a/tests/ui/wildcard_imports.stderr b/tests/ui/wildcard_imports.stderr index 6b469cdfc444..f7baf234c2f8 100644 --- a/tests/ui/wildcard_imports.stderr +++ b/tests/ui/wildcard_imports.stderr @@ -37,55 +37,55 @@ LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:95:13 + --> $DIR/wildcard_imports.rs:97:13 | LL | use crate::fn_mod::*; | ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:101:75 + --> $DIR/wildcard_imports.rs:103:75 | LL | use wildcard_imports_helper::inner::inner_for_self_import::{self, *}; | ^ help: try: `inner_extern_foo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:102:13 + --> $DIR/wildcard_imports.rs:104:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:113:20 + --> $DIR/wildcard_imports.rs:116:20 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^ help: try: `inner::inner_foo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:113:30 + --> $DIR/wildcard_imports.rs:116:30 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^^ help: try: `inner2::inner_bar` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:120:13 + --> $DIR/wildcard_imports.rs:123:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:149:9 + --> $DIR/wildcard_imports.rs:152:9 | LL | use crate::in_fn_test::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:158:9 + --> $DIR/wildcard_imports.rs:161:9 | LL | use crate:: in_fn_test:: * ; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:159:9 + --> $DIR/wildcard_imports.rs:162:9 | LL | use crate:: fn_mod:: | _________^ @@ -93,37 +93,37 @@ LL | | *; | |_________^ help: try: `crate:: fn_mod::foo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:170:13 + --> $DIR/wildcard_imports.rs:173:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:205:17 + --> $DIR/wildcard_imports.rs:208:17 | LL | use super::*; | ^^^^^^^^ help: try: `super::insidefoo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:213:13 + --> $DIR/wildcard_imports.rs:216:13 | -LL | use super_imports::*; - | ^^^^^^^^^^^^^^^^ help: try: `super_imports::foofoo` +LL | use crate::super_imports::*; + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:222:17 + --> $DIR/wildcard_imports.rs:225:17 | LL | use super::super::*; | ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:231:13 + --> $DIR/wildcard_imports.rs:234:13 | LL | use super::super::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports.rs:239:13 + --> $DIR/wildcard_imports.rs:242:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` diff --git a/tests/ui/wildcard_imports_2021.edition2018.fixed b/tests/ui/wildcard_imports_2021.edition2018.fixed index 6d534a10edcd..8a63375676ef 100644 --- a/tests/ui/wildcard_imports_2021.edition2018.fixed +++ b/tests/ui/wildcard_imports_2021.edition2018.fixed @@ -1,8 +1,8 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix -// aux-build:wildcard_imports_helper.rs +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix +//@aux-build:wildcard_imports_helper.rs #![warn(clippy::wildcard_imports)] #![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)] @@ -106,6 +106,7 @@ mod in_fn_test { } fn test_inner_nested() { + #[rustfmt::skip] use self::{inner::inner_foo, inner2::inner_bar}; inner_foo(); diff --git a/tests/ui/wildcard_imports_2021.edition2018.stderr b/tests/ui/wildcard_imports_2021.edition2018.stderr index acca9f651b47..af9ae6e786c9 100644 --- a/tests/ui/wildcard_imports_2021.edition2018.stderr +++ b/tests/ui/wildcard_imports_2021.edition2018.stderr @@ -55,37 +55,37 @@ LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:109:20 + --> $DIR/wildcard_imports_2021.rs:110:20 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^ help: try: `inner::inner_foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:109:30 + --> $DIR/wildcard_imports_2021.rs:110:30 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^^ help: try: `inner2::inner_bar` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:116:13 + --> $DIR/wildcard_imports_2021.rs:117:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:145:9 + --> $DIR/wildcard_imports_2021.rs:146:9 | LL | use crate::in_fn_test::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:154:9 + --> $DIR/wildcard_imports_2021.rs:155:9 | LL | use crate:: in_fn_test:: * ; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:155:9 + --> $DIR/wildcard_imports_2021.rs:156:9 | LL | use crate:: fn_mod:: | _________^ @@ -93,37 +93,37 @@ LL | | *; | |_________^ help: try: `crate:: fn_mod::foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:166:13 + --> $DIR/wildcard_imports_2021.rs:167:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:201:17 + --> $DIR/wildcard_imports_2021.rs:202:17 | LL | use super::*; | ^^^^^^^^ help: try: `super::insidefoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:209:13 + --> $DIR/wildcard_imports_2021.rs:210:13 | LL | use crate::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:218:17 + --> $DIR/wildcard_imports_2021.rs:219:17 | LL | use super::super::*; | ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:227:13 + --> $DIR/wildcard_imports_2021.rs:228:13 | LL | use super::super::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:235:13 + --> $DIR/wildcard_imports_2021.rs:236:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` diff --git a/tests/ui/wildcard_imports_2021.edition2021.fixed b/tests/ui/wildcard_imports_2021.edition2021.fixed index 6d534a10edcd..8a63375676ef 100644 --- a/tests/ui/wildcard_imports_2021.edition2021.fixed +++ b/tests/ui/wildcard_imports_2021.edition2021.fixed @@ -1,8 +1,8 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix -// aux-build:wildcard_imports_helper.rs +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix +//@aux-build:wildcard_imports_helper.rs #![warn(clippy::wildcard_imports)] #![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)] @@ -106,6 +106,7 @@ mod in_fn_test { } fn test_inner_nested() { + #[rustfmt::skip] use self::{inner::inner_foo, inner2::inner_bar}; inner_foo(); diff --git a/tests/ui/wildcard_imports_2021.edition2021.stderr b/tests/ui/wildcard_imports_2021.edition2021.stderr index acca9f651b47..af9ae6e786c9 100644 --- a/tests/ui/wildcard_imports_2021.edition2021.stderr +++ b/tests/ui/wildcard_imports_2021.edition2021.stderr @@ -55,37 +55,37 @@ LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:109:20 + --> $DIR/wildcard_imports_2021.rs:110:20 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^ help: try: `inner::inner_foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:109:30 + --> $DIR/wildcard_imports_2021.rs:110:30 | LL | use self::{inner::*, inner2::*}; | ^^^^^^^^^ help: try: `inner2::inner_bar` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:116:13 + --> $DIR/wildcard_imports_2021.rs:117:13 | LL | use wildcard_imports_helper::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:145:9 + --> $DIR/wildcard_imports_2021.rs:146:9 | LL | use crate::in_fn_test::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:154:9 + --> $DIR/wildcard_imports_2021.rs:155:9 | LL | use crate:: in_fn_test:: * ; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:155:9 + --> $DIR/wildcard_imports_2021.rs:156:9 | LL | use crate:: fn_mod:: | _________^ @@ -93,37 +93,37 @@ LL | | *; | |_________^ help: try: `crate:: fn_mod::foo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:166:13 + --> $DIR/wildcard_imports_2021.rs:167:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:201:17 + --> $DIR/wildcard_imports_2021.rs:202:17 | LL | use super::*; | ^^^^^^^^ help: try: `super::insidefoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:209:13 + --> $DIR/wildcard_imports_2021.rs:210:13 | LL | use crate::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:218:17 + --> $DIR/wildcard_imports_2021.rs:219:17 | LL | use super::super::*; | ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:227:13 + --> $DIR/wildcard_imports_2021.rs:228:13 | LL | use super::super::super_imports::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo` error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:235:13 + --> $DIR/wildcard_imports_2021.rs:236:13 | LL | use super::*; | ^^^^^^^^ help: try: `super::foofoo` diff --git a/tests/ui/wildcard_imports_2021.rs b/tests/ui/wildcard_imports_2021.rs index b5ed58e68136..52cd2c82854f 100644 --- a/tests/ui/wildcard_imports_2021.rs +++ b/tests/ui/wildcard_imports_2021.rs @@ -1,8 +1,8 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix -// aux-build:wildcard_imports_helper.rs +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix +//@aux-build:wildcard_imports_helper.rs #![warn(clippy::wildcard_imports)] #![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)] @@ -106,6 +106,7 @@ mod in_fn_test { } fn test_inner_nested() { + #[rustfmt::skip] use self::{inner::*, inner2::*}; inner_foo(); diff --git a/tests/ui/wildcard_imports_2021.stderr b/tests/ui/wildcard_imports_2021.stderr deleted file mode 100644 index 92f6d31530fa..000000000000 --- a/tests/ui/wildcard_imports_2021.stderr +++ /dev/null @@ -1,132 +0,0 @@ -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:9:5 - | -LL | use crate::fn_mod::*; - | ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo` - | - = note: `-D clippy::wildcard-imports` implied by `-D warnings` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:10:5 - | -LL | use crate::mod_mod::*; - | ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:11:5 - | -LL | use crate::multi_fn_mod::*; - | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:12:5 - | -LL | use crate::struct_mod::*; - | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:15:5 - | -LL | use wildcard_imports_helper::inner::inner_for_self_import::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:17:5 - | -LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:87:13 - | -LL | use crate::fn_mod::*; - | ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:93:75 - | -LL | use wildcard_imports_helper::inner::inner_for_self_import::{self, *}; - | ^ help: try: `inner_extern_foo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:94:13 - | -LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:105:20 - | -LL | use self::{inner::*, inner2::*}; - | ^^^^^^^^ help: try: `inner::inner_foo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:105:30 - | -LL | use self::{inner::*, inner2::*}; - | ^^^^^^^^^ help: try: `inner2::inner_bar` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:112:13 - | -LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:141:9 - | -LL | use crate::in_fn_test::*; - | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:150:9 - | -LL | use crate:: in_fn_test:: * ; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:151:9 - | -LL | use crate:: fn_mod:: - | _________^ -LL | | *; - | |_________^ help: try: `crate:: fn_mod::foo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:162:13 - | -LL | use super::*; - | ^^^^^^^^ help: try: `super::foofoo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:197:17 - | -LL | use super::*; - | ^^^^^^^^ help: try: `super::insidefoo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:205:13 - | -LL | use crate::super_imports::*; - | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:214:17 - | -LL | use super::super::*; - | ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:223:13 - | -LL | use super::super::super_imports::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:231:13 - | -LL | use super::*; - | ^^^^^^^^ help: try: `super::foofoo` - -error: aborting due to 21 previous errors - diff --git a/tests/ui/wildcard_imports_cfgtest.rs b/tests/ui/wildcard_imports_cfgtest.rs new file mode 100644 index 000000000000..9eb760ed9b94 --- /dev/null +++ b/tests/ui/wildcard_imports_cfgtest.rs @@ -0,0 +1,27 @@ +<<<<<<< HEAD +<<<<<<< HEAD +//@compile-flags: --test +======= +// compile-flags: --test +>>>>>>> ba0e7e88c (Now the lint ignores any crates with `--cfg test`) +======= +//@compile-flags: --test +>>>>>>> 4c3e2ff2a (Fix header) + +#![warn(clippy::wildcard_imports)] +#![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)] + +// Test for #10580, the lint should ignore it because of the crate's cfg test flag. + +fn foofoo() {} + +mod outer { + mod inner { + use super::super::*; + fn barbar() { + let _ = foofoo(); + } + } +} + +fn main() {} diff --git a/tests/ui/write_literal.stderr b/tests/ui/write_literal.stderr index 1e306ae28a26..8b72c8bd2823 100644 --- a/tests/ui/write_literal.stderr +++ b/tests/ui/write_literal.stderr @@ -5,7 +5,7 @@ LL | write!(v, "Hello {}", "world"); | ^^^^^^^ | = note: `-D clippy::write-literal` implied by `-D warnings` -help: try this +help: try | LL - write!(v, "Hello {}", "world"); LL + write!(v, "Hello world"); @@ -17,7 +17,7 @@ error: literal with an empty format string LL | writeln!(v, "Hello {} {}", world, "world"); | ^^^^^^^ | -help: try this +help: try | LL - writeln!(v, "Hello {} {}", world, "world"); LL + writeln!(v, "Hello {} world", world); @@ -29,7 +29,7 @@ error: literal with an empty format string LL | writeln!(v, "Hello {}", "world"); | ^^^^^^^ | -help: try this +help: try | LL - writeln!(v, "Hello {}", "world"); LL + writeln!(v, "Hello world"); @@ -41,7 +41,7 @@ error: literal with an empty format string LL | writeln!(v, "{} {:.4}", "a literal", 5); | ^^^^^^^^^^^ | -help: try this +help: try | LL - writeln!(v, "{} {:.4}", "a literal", 5); LL + writeln!(v, "a literal {:.4}", 5); @@ -53,7 +53,7 @@ error: literal with an empty format string LL | writeln!(v, "{0} {1}", "hello", "world"); | ^^^^^^^ | -help: try this +help: try | LL - writeln!(v, "{0} {1}", "hello", "world"); LL + writeln!(v, "hello {1}", "world"); @@ -65,7 +65,7 @@ error: literal with an empty format string LL | writeln!(v, "{0} {1}", "hello", "world"); | ^^^^^^^ | -help: try this +help: try | LL - writeln!(v, "{0} {1}", "hello", "world"); LL + writeln!(v, "{0} world", "hello"); @@ -77,7 +77,7 @@ error: literal with an empty format string LL | writeln!(v, "{1} {0}", "hello", "world"); | ^^^^^^^ | -help: try this +help: try | LL - writeln!(v, "{1} {0}", "hello", "world"); LL + writeln!(v, "world {0}", "hello"); @@ -89,7 +89,7 @@ error: literal with an empty format string LL | writeln!(v, "{1} {0}", "hello", "world"); | ^^^^^^^ | -help: try this +help: try | LL - writeln!(v, "{1} {0}", "hello", "world"); LL + writeln!(v, "{1} hello", "world"); @@ -101,7 +101,7 @@ error: literal with an empty format string LL | writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); | ^^^^^^^ | -help: try this +help: try | LL - writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); LL + writeln!(v, "hello {bar}", bar = "world"); @@ -113,7 +113,7 @@ error: literal with an empty format string LL | writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); | ^^^^^^^ | -help: try this +help: try | LL - writeln!(v, "{foo} {bar}", foo = "hello", bar = "world"); LL + writeln!(v, "{foo} world", foo = "hello"); @@ -125,7 +125,7 @@ error: literal with an empty format string LL | writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); | ^^^^^^^ | -help: try this +help: try | LL - writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); LL + writeln!(v, "world {foo}", foo = "hello"); @@ -137,7 +137,7 @@ error: literal with an empty format string LL | writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); | ^^^^^^^ | -help: try this +help: try | LL - writeln!(v, "{bar} {foo}", foo = "hello", bar = "world"); LL + writeln!(v, "{bar} hello", bar = "world"); diff --git a/tests/ui/write_literal_2.rs b/tests/ui/write_literal_2.rs index 55a11daa1d34..0d2932d93e7d 100644 --- a/tests/ui/write_literal_2.rs +++ b/tests/ui/write_literal_2.rs @@ -1,5 +1,13 @@ #![allow(unused_must_use)] -#![warn(clippy::write_literal)] +<<<<<<< HEAD +<<<<<<< HEAD +#![warn(clippy::needless_raw_strings, clippy::write_literal)] +======= +#![warn(clippy::needless_raw_string, clippy::write_literal)] +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= +#![warn(clippy::needless_raw_strings, clippy::write_literal)] +>>>>>>> 8cb6c8699 (change category and refactor) use std::io::Write; diff --git a/tests/ui/write_literal_2.stderr b/tests/ui/write_literal_2.stderr index d5956db9ff0b..a6a226dff2b3 100644 --- a/tests/ui/write_literal_2.stderr +++ b/tests/ui/write_literal_2.stderr @@ -1,3 +1,19 @@ +error: unnecessary raw string literal + --> $DIR/write_literal_2.rs:10:24 + | +LL | writeln!(v, r"{}", r"{hello}"); + | ^^^^^^^^^^ help: try: `"{hello}"` + | +<<<<<<< HEAD +<<<<<<< HEAD + = note: `-D clippy::needless-raw-strings` implied by `-D warnings` +======= + = note: `-D clippy::needless-raw-string` implied by `-D warnings` +>>>>>>> bc744eb82 (new lint `needless_raw_string` + refactor a bit) +======= + = note: `-D clippy::needless-raw-strings` implied by `-D warnings` +>>>>>>> 8cb6c8699 (change category and refactor) + error: literal with an empty format string --> $DIR/write_literal_2.rs:9:23 | @@ -5,7 +21,7 @@ LL | writeln!(v, "{}", "{hello}"); | ^^^^^^^^^ | = note: `-D clippy::write-literal` implied by `-D warnings` -help: try this +help: try | LL - writeln!(v, "{}", "{hello}"); LL + writeln!(v, "{{hello}}"); @@ -17,7 +33,7 @@ error: literal with an empty format string LL | writeln!(v, r"{}", r"{hello}"); | ^^^^^^^^^^ | -help: try this +help: try | LL - writeln!(v, r"{}", r"{hello}"); LL + writeln!(v, r"{{hello}}"); @@ -29,7 +45,7 @@ error: literal with an empty format string LL | writeln!(v, "{}", '/''); | ^^^^ | -help: try this +help: try | LL - writeln!(v, "{}", '/''); LL + writeln!(v, "'"); @@ -41,7 +57,7 @@ error: literal with an empty format string LL | writeln!(v, "{}", '"'); | ^^^ | -help: try this +help: try | LL - writeln!(v, "{}", '"'); LL + writeln!(v, "/""); @@ -59,7 +75,7 @@ error: literal with an empty format string LL | writeln!(v, r"{}", '/''); | ^^^^ | -help: try this +help: try | LL - writeln!(v, r"{}", '/''); LL + writeln!(v, r"'"); @@ -72,7 +88,7 @@ LL | / "hello / LL | | world!" | |_______________^ | -help: try this +help: try | LL ~ "some hello / LL ~ world!" @@ -84,10 +100,10 @@ error: literal with an empty format string LL | "1", "2", "3", | ^^^ | -help: try this +help: try | LL ~ "some 1/ -LL ~ {} / {}", "2", "3", +LL ~ {} // {}", "2", "3", | error: literal with an empty format string @@ -96,9 +112,9 @@ error: literal with an empty format string LL | "1", "2", "3", | ^^^ | -help: try this +help: try | -LL ~ 2 / {}", +LL ~ 2 // {}", LL ~ "1", "3", | @@ -108,45 +124,45 @@ error: literal with an empty format string LL | "1", "2", "3", | ^^^ | -help: try this +help: try | -LL ~ {} / 3", +LL ~ {} // 3", LL ~ "1", "2", | error: literal with an empty format string --> $DIR/write_literal_2.rs:27:23 | -LL | writeln!(v, "{}", "/"); +LL | writeln!(v, "{}", "//"); | ^^^^ | -help: try this +help: try | -LL - writeln!(v, "{}", "/"); -LL + writeln!(v, "/"); +LL - writeln!(v, "{}", "//"); +LL + writeln!(v, "//"); | error: literal with an empty format string --> $DIR/write_literal_2.rs:28:24 | -LL | writeln!(v, r"{}", "/"); +LL | writeln!(v, r"{}", "//"); | ^^^^ | -help: try this +help: try | -LL - writeln!(v, r"{}", "/"); +LL - writeln!(v, r"{}", "//"); LL + writeln!(v, r"/"); | error: literal with an empty format string --> $DIR/write_literal_2.rs:29:26 | -LL | writeln!(v, r#"{}"#, "/"); +LL | writeln!(v, r#"{}"#, "//"); | ^^^^ | -help: try this +help: try | -LL - writeln!(v, r#"{}"#, "/"); +LL - writeln!(v, r#"{}"#, "//"); LL + writeln!(v, r#"/"#); | @@ -156,10 +172,10 @@ error: literal with an empty format string LL | writeln!(v, "{}", r"/"); | ^^^^ | -help: try this +help: try | LL - writeln!(v, "{}", r"/"); -LL + writeln!(v, "/"); +LL + writeln!(v, "//"); | error: literal with an empty format string @@ -168,7 +184,7 @@ error: literal with an empty format string LL | writeln!(v, "{}", "/r"); | ^^^^ | -help: try this +help: try | LL - writeln!(v, "{}", "/r"); LL + writeln!(v, "/r"); @@ -186,5 +202,5 @@ error: literal with an empty format string LL | writeln!(v, r#"{}{}"#, '#', '"'); // hard mode | ^^^ -error: aborting due to 17 previous errors +error: aborting due to 18 previous errors diff --git a/tests/ui/write_with_newline.fixed b/tests/ui/write_with_newline.fixed new file mode 100644 index 000000000000..0a10e526a2f5 --- /dev/null +++ b/tests/ui/write_with_newline.fixed @@ -0,0 +1,63 @@ +// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934 +// //@run-rustfix + +#![allow(clippy::write_literal)] +#![warn(clippy::write_with_newline)] + +use std::io::Write; + +fn main() { + let mut v = Vec::new(); + + // These should fail + writeln!(v, "Hello"); + writeln!(v, "Hello {}", "world"); + writeln!(v, "Hello {} {}", "world", "#2"); + writeln!(v, "{}", 1265); + writeln!(v); + + // These should be fine + write!(v, ""); + write!(v, "Hello"); + writeln!(v, "Hello"); + writeln!(v, "Hello\n"); + writeln!(v, "Hello {}\n", "world"); + write!(v, "Issue\n{}", 1265); + write!(v, "{}", 1265); + write!(v, "\n{}", 1275); + write!(v, "\n\n"); + write!(v, "like eof\n\n"); + write!(v, "Hello {} {}\n\n", "world", "#2"); + writeln!(v, "\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126 + writeln!(v, "\nbla\n\n"); // #3126 + + // Escaping + write!(v, "\\n"); // #3514 + writeln!(v, "\\"); // should fail + write!(v, "\\\\n"); + + // Raw strings + write!(v, r"\n"); // #3778 + + // Literal newlines should also fail + writeln!( + v + ); + writeln!( + v + ); + + // Don't warn on CRLF (#4208) + write!(v, "\r\n"); + write!(v, "foo\r\n"); + writeln!(v, "\\r"); // warns + write!(v, "foo\rbar\n"); + + // Ignore expanded format strings + macro_rules! newline { + () => { + "\n" + }; + } + write!(v, newline!()); +} diff --git a/tests/ui/write_with_newline.rs b/tests/ui/write_with_newline.rs index b79364c8758c..35bd9e7f3a07 100644 --- a/tests/ui/write_with_newline.rs +++ b/tests/ui/write_with_newline.rs @@ -1,5 +1,5 @@ // FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934 -// // run-rustfix +// #![allow(clippy::write_literal)] #![warn(clippy::write_with_newline)] @@ -54,7 +54,7 @@ fn main() { // Don't warn on CRLF (#4208) write!(v, "\r\n"); write!(v, "foo\r\n"); - write!(v, "\\r\n"); //~ ERROR + write!(v, "\\r\n"); write!(v, "foo\rbar\n"); // Ignore expanded format strings diff --git a/tests/ui/write_with_newline.stderr b/tests/ui/write_with_newline.stderr index 2baaea166d8e..9b8c3a5892c3 100644 --- a/tests/ui/write_with_newline.stderr +++ b/tests/ui/write_with_newline.stderr @@ -62,13 +62,13 @@ LL + writeln!(v); error: using `write!()` with a format string that ends in a single newline --> $DIR/write_with_newline.rs:36:5 | -LL | write!(v, "//n"); // should fail +LL | write!(v, "///n"); // should fail | ^^^^^^^^^^^^^^^^^ | help: use `writeln!` instead | -LL - write!(v, "//n"); // should fail -LL + writeln!(v, "/"); // should fail +LL - write!(v, "///n"); // should fail +LL + writeln!(v, "//"); // should fail | error: using `write!()` with a format string that ends in a single newline @@ -106,13 +106,22 @@ LL ~ v error: using `write!()` with a format string that ends in a single newline --> $DIR/write_with_newline.rs:57:5 | -LL | write!(v, "/r/n"); //~ ERROR +<<<<<<< HEAD +LL | write!(v, "//r/n"); +======= +LL | write!(v, "/r/n"); +>>>>>>> e4f5d83fa (Fixed formatting.) | ^^^^^^^^^^^^^^^^^^ | help: use `writeln!` instead | -LL - write!(v, "/r/n"); //~ ERROR -LL + writeln!(v, "/r"); //~ ERROR +<<<<<<< HEAD +LL - write!(v, "//r/n"); +LL + writeln!(v, "//r"); +======= +LL - write!(v, "/r/n"); +LL + writeln!(v, "/r"); +>>>>>>> e4f5d83fa (Fixed formatting.) | error: aborting due to 9 previous errors diff --git a/tests/ui/writeln_empty_string.fixed b/tests/ui/writeln_empty_string.fixed index e7d94acd130d..45dedd9ead6a 100644 --- a/tests/ui/writeln_empty_string.fixed +++ b/tests/ui/writeln_empty_string.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_must_use)] #![warn(clippy::writeln_empty_string)] diff --git a/tests/ui/writeln_empty_string.rs b/tests/ui/writeln_empty_string.rs index 662c62f02116..3b9f51a15d2f 100644 --- a/tests/ui/writeln_empty_string.rs +++ b/tests/ui/writeln_empty_string.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_must_use)] #![warn(clippy::writeln_empty_string)] diff --git a/tests/ui/zero_ptr.fixed b/tests/ui/zero_ptr.fixed index 489aa4121a3a..bed38ecafc7e 100644 --- a/tests/ui/zero_ptr.fixed +++ b/tests/ui/zero_ptr.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix pub fn foo(_const: *const f32, _mut: *mut i64) {} fn main() { diff --git a/tests/ui/zero_ptr.rs b/tests/ui/zero_ptr.rs index c3b55ef9ebd9..b7b778915a8f 100644 --- a/tests/ui/zero_ptr.rs +++ b/tests/ui/zero_ptr.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix pub fn foo(_const: *const f32, _mut: *mut i64) {} fn main() { diff --git a/tests/ui/zero_ptr_no_std.fixed b/tests/ui/zero_ptr_no_std.fixed index 8906c776977a..7afd80ccaca6 100644 --- a/tests/ui/zero_ptr_no_std.fixed +++ b/tests/ui/zero_ptr_no_std.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lang_items, start, libc)] #![no_std] diff --git a/tests/ui/zero_ptr_no_std.rs b/tests/ui/zero_ptr_no_std.rs index 379c1b18d299..05a0587d22bc 100644 --- a/tests/ui/zero_ptr_no_std.rs +++ b/tests/ui/zero_ptr_no_std.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lang_items, start, libc)] #![no_std] diff --git a/tests/workspace.rs b/tests/workspace.rs index c9cbc50546cf..699ab2be199a 100644 --- a/tests/workspace.rs +++ b/tests/workspace.rs @@ -6,6 +6,46 @@ use test_utils::{CARGO_CLIPPY_PATH, IS_RUSTC_TEST_SUITE}; mod test_utils; +#[test] +fn test_module_style_with_dep_in_subdir() { + if IS_RUSTC_TEST_SUITE { + return; + } + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let target_dir = root.join("target").join("workspace_test"); + let cwd = root.join("tests/workspace_test"); + + // Make sure we start with a clean state + Command::new("cargo") + .current_dir(&cwd) + .env("CARGO_TARGET_DIR", &target_dir) + .arg("clean") + .args(["-p", "pass-no-mod-with-dep-in-subdir"]) + .args(["-p", "pass-mod-with-dep-in-subdir"]) + .output() + .unwrap(); + + // [#8887](https://github.com/rust-lang/rust-clippy/issues/8887) + // `mod.rs` checks should not be applied to crate dependencies + // located in the subdirectory of workspace + let output = Command::new(&*CARGO_CLIPPY_PATH) + .current_dir(&cwd) + .env("CARGO_INCREMENTAL", "0") + .env("CARGO_TARGET_DIR", &target_dir) + .arg("clippy") + .args(["-p", "pass-no-mod-with-dep-in-subdir"]) + .args(["-p", "pass-mod-with-dep-in-subdir"]) + .arg("--") + .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir + .output() + .unwrap(); + + println!("status: {}", output.status); + println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); + println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); + assert!(output.status.success()); +} + #[test] fn test_no_deps_ignores_path_deps_in_workspaces() { if IS_RUSTC_TEST_SUITE { diff --git a/tests/workspace_test/Cargo.toml b/tests/workspace_test/Cargo.toml index bf5b4ca5288a..d24b278ccc28 100644 --- a/tests/workspace_test/Cargo.toml +++ b/tests/workspace_test/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2018" [workspace] -members = ["subcrate"] +members = ["subcrate", "module_style/pass_no_mod_with_dep_in_subdir", "module_style/pass_mod_with_dep_in_subdir"] diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/Cargo.toml b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/Cargo.toml new file mode 100644 index 000000000000..15dcde4e30a1 --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "pass-mod-with-dep-in-subdir" +version = "0.1.0" +edition = "2018" +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +dep-no-mod = { path = "dep_no_mod"} diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/Cargo.toml b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/Cargo.toml new file mode 100644 index 000000000000..55569bc25ed7 --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "dep-no-mod" +version = "0.1.0" +edition = "2018" +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo.rs new file mode 100644 index 000000000000..7b0966a45867 --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo.rs @@ -0,0 +1,2 @@ +pub mod hello; +pub struct Thing; diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo/hello.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo/hello.rs new file mode 100644 index 000000000000..99940dce528a --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo/hello.rs @@ -0,0 +1 @@ +pub struct Hello; diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/lib.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/lib.rs new file mode 100644 index 000000000000..c62f9acbf2cb --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/lib.rs @@ -0,0 +1,5 @@ +pub mod foo; + +pub fn foo() { + let _ = foo::Thing; +} diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/bad/mod.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/bad/mod.rs new file mode 100644 index 000000000000..f19ab10d5fb0 --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/bad/mod.rs @@ -0,0 +1 @@ +pub struct Thing; diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/main.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/main.rs new file mode 100644 index 000000000000..5cb4795e9451 --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/main.rs @@ -0,0 +1,13 @@ +#![deny(clippy::self_named_module_files)] + +mod bad; +mod more; +extern crate dep_no_mod; + +fn main() { + let _ = bad::Thing; + let _ = more::foo::Foo; + let _ = more::inner::Inner; + let _ = dep_no_mod::foo::Thing; + let _ = dep_no_mod::foo::hello::Hello; +} diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/foo.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/foo.rs new file mode 100644 index 000000000000..4a835673a596 --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/foo.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/inner/mod.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/inner/mod.rs new file mode 100644 index 000000000000..aa84f78cc2ca --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/inner/mod.rs @@ -0,0 +1 @@ +pub struct Inner; diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/mod.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/mod.rs new file mode 100644 index 000000000000..d79569f78ffb --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/mod.rs @@ -0,0 +1,2 @@ +pub mod foo; +pub mod inner; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/Cargo.toml b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/Cargo.toml new file mode 100644 index 000000000000..060cb18dc9f9 --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "pass-no-mod-with-dep-in-subdir" +version = "0.1.0" +edition = "2018" +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +dep-with-mod = { path = "dep_with_mod"} diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/Cargo.toml b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/Cargo.toml new file mode 100644 index 000000000000..b25725cd5610 --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "dep-with-mod" +version = "0.1.0" +edition = "2018" +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/lib.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/lib.rs new file mode 100644 index 000000000000..4647424f2c2f --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/lib.rs @@ -0,0 +1,7 @@ +pub mod with_mod; + +pub fn foo() { + let _ = with_mod::Thing; + let _ = with_mod::inner::stuff::Inner; + let _ = with_mod::inner::stuff::most::Snarks; +} diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner.rs new file mode 100644 index 000000000000..91cd540a28fd --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner.rs @@ -0,0 +1 @@ +pub mod stuff; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff.rs new file mode 100644 index 000000000000..7713fa9d35c4 --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff.rs @@ -0,0 +1,3 @@ +pub mod most; + +pub struct Inner; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff/most.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff/most.rs new file mode 100644 index 000000000000..5a5eaf9670f9 --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff/most.rs @@ -0,0 +1 @@ +pub struct Snarks; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/mod.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/mod.rs new file mode 100644 index 000000000000..a12734db7cb5 --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/mod.rs @@ -0,0 +1,3 @@ +pub mod inner; + +pub struct Thing; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/good.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/good.rs new file mode 100644 index 000000000000..f19ab10d5fb0 --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/good.rs @@ -0,0 +1 @@ +pub struct Thing; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/main.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/main.rs new file mode 100644 index 000000000000..42eb99cd7a3e --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/main.rs @@ -0,0 +1,9 @@ +#![deny(clippy::mod_module_files)] + +mod good; +pub use dep_with_mod::with_mod::Thing; + +fn main() { + let _ = good::Thing; + let _ = dep_with_mod::with_mod::Thing; +} diff --git a/triagebot.toml b/triagebot.toml index 3f8f6a7b98c2..c40b71f6ca7d 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -17,9 +17,9 @@ contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIB [assign.owners] "/.github" = ["@flip1995"] +"/book" = ["@flip1995"] "/util/gh-pages" = ["@xFrednet"] "*" = [ - "@flip1995", "@Manishearth", "@llogiq", "@giraffate", diff --git a/util/etc/vscode-tasks.json b/util/etc/vscode-tasks.json index ab98f9b4154a..38e31b337a06 100644 --- a/util/etc/vscode-tasks.json +++ b/util/etc/vscode-tasks.json @@ -47,9 +47,9 @@ "group": "test" }, { - "label": "cargo dev bless", + "label": "bless ui tests", "type": "shell", - "command": "cargo dev bless", + "command": "cargo bless", "problemMatcher": [], "group": "none" } diff --git a/util/fetch_prs_between.sh b/util/fetch_prs_between.sh index 6865abf971b2..fa7560b6929d 100755 --- a/util/fetch_prs_between.sh +++ b/util/fetch_prs_between.sh @@ -6,15 +6,20 @@ # If you want to use this to update the Clippy changelog, be sure to manually # exclude the non-user facing changes like 'rustup' PRs, typo fixes, etc. -first=$1 -last=$2 +set -e IFS=' ' -for pr in $(git log --oneline --grep "Merge #" --grep "Merge pull request" --grep "Auto merge of" --grep "Rollup merge of" "$first...$last" | sort -rn | uniq); do +for pr in $(git log --oneline --merges --first-parent "$1...$2"); do id=$(echo "$pr" | rg -o '#[0-9]{3,5}' | cut -c 2-) commit=$(echo "$pr" | cut -d' ' -f 1) message=$(git --no-pager show --pretty=medium "$commit") + + if [[ -z "$newest_pr" ]]; then + newest_pr="$id" + fi + oldest_pr="$id" + if [[ -n $(echo "$message" | rg "^[\s]{4}changelog: [nN]one\.*$") ]]; then continue fi @@ -25,3 +30,14 @@ for pr in $(git log --oneline --grep "Merge #" --grep "Merge pull request" --gre echo "---------------------------------------------------------" echo done + +newest_merged_at="$(gh pr view -R rust-lang/rust-clippy --json mergedAt $newest_pr -q .mergedAt)" +oldest_merged_at="$(gh pr view -R rust-lang/rust-clippy --json mergedAt $oldest_pr -q .mergedAt)" + +query="merged:$oldest_merged_at..$newest_merged_at base:master" +encoded_query="$(echo $query | sed 's/ /+/g; s/:/%3A/g')" + +pr_link="https://github.com/rust-lang/rust-clippy/pulls?q=$encoded_query" +count="$(gh api -X GET search/issues -f "q=$query repo:rust-lang/rust-clippy" -q .total_count)" + +echo "[View all $count merged pull requests]($pr_link)" diff --git a/util/gh-pages/index.html b/util/gh-pages/index.html index e46ad2c6e0ee..99e211654d19 100644 --- a/util/gh-pages/index.html +++ b/util/gh-pages/index.html @@ -501,9 +501,11 @@

Clippy Lints

- + - @@ -517,7 +519,8 @@

Clippy Lints

{{lint.id}} - + 📋 @@ -564,7 +567,7 @@

- Fork me on Github + Fork me on GitHub diff --git a/util/gh-pages/script.js b/util/gh-pages/script.js index 1c16ecd6b0b1..9e302a36e3b8 100644 --- a/util/gh-pages/script.js +++ b/util/gh-pages/script.js @@ -24,9 +24,9 @@ target.scrollIntoView(); } - function scrollToLintByURL($scope) { - var removeListener = $scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) { - scrollToLint(window.location.hash.slice(1)); + function scrollToLintByURL($scope, $location) { + var removeListener = $scope.$on('ngRepeatFinished', function (ngRepeatFinishedEvent) { + scrollToLint($location.path().substring(1)); removeListener(); }); } @@ -106,10 +106,18 @@ } }; }) - .controller("lintList", function ($scope, $http, $timeout) { +<<<<<<< HEAD +<<<<<<< HEAD + .controller("lintList", function ($scope, $http, $location, $timeout) { +======= + .controller("lintList", function ($scope, $http, $location) { +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= + .controller("lintList", function ($scope, $http, $location, $timeout) { +>>>>>>> a865d8432 (Clippy Lints page - Delay updating of the URL in response to search input) // Level filter var LEVEL_FILTERS_DEFAULT = {allow: true, warn: true, deny: true, none: true}; - $scope.levels = LEVEL_FILTERS_DEFAULT; + $scope.levels = { ...LEVEL_FILTERS_DEFAULT }; $scope.byLevels = function (lint) { return $scope.levels[lint.level]; }; @@ -146,6 +154,338 @@ "=": {enabled: false, minorVersion: null }, }; + // Map the versionFilters to the query parameters in a way that is easier to work with in a URL + const versionFilterKeyMap = { + "≥": "gte", + "≤": "lte", + "=": "eq" + }; + const reverseVersionFilterKeyMap = Object.fromEntries( + Object.entries(versionFilterKeyMap).map(([key, value]) => [value, key]) + ); + + // loadFromURLParameters retrieves filter settings from the URL parameters and assigns them + // to corresponding $scope variables. + function loadFromURLParameters() { + // Extract parameters from URL + const urlParameters = $location.search(); + + // Define a helper function that assigns URL parameters to a provided scope variable +<<<<<<< HEAD +<<<<<<< HEAD + const handleParameter = (parameter, scopeVariable, defaultValues) => { +======= + const handleParameter = (parameter, scopeVariable) => { +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= + const handleParameter = (parameter, scopeVariable, defaultValues) => { +>>>>>>> 7c1bca4be (Handle back/forward when using URL parameters for filter states) + if (urlParameters[parameter]) { + const items = urlParameters[parameter].split(','); + for (const key in scopeVariable) { + if (scopeVariable.hasOwnProperty(key)) { + scopeVariable[key] = items.includes(key); + } + } +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 7c1bca4be (Handle back/forward when using URL parameters for filter states) + } else if (defaultValues) { + for (const key in defaultValues) { + if (scopeVariable.hasOwnProperty(key)) { + scopeVariable[key] = defaultValues[key]; + } + } +<<<<<<< HEAD + } + }; + + handleParameter('levels', $scope.levels, LEVEL_FILTERS_DEFAULT); + handleParameter('groups', $scope.groups, GROUPS_FILTER_DEFAULT); +======= + } + }; + + handleParameter('levels', $scope.levels); + handleParameter('groups', $scope.groups); +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= + } + }; + + handleParameter('levels', $scope.levels, LEVEL_FILTERS_DEFAULT); + handleParameter('groups', $scope.groups, GROUPS_FILTER_DEFAULT); +>>>>>>> 7c1bca4be (Handle back/forward when using URL parameters for filter states) + + // Handle 'versions' parameter separately because it needs additional processing + if (urlParameters.versions) { + const versionFilters = urlParameters.versions.split(','); + for (const versionFilter of versionFilters) { + const [key, minorVersion] = versionFilter.split(':'); + const parsedMinorVersion = parseInt(minorVersion); + + // Map the key from the URL parameter to its original form + const originalKey = reverseVersionFilterKeyMap[key]; + + if (originalKey in $scope.versionFilters && !isNaN(parsedMinorVersion)) { + $scope.versionFilters[originalKey].enabled = true; + $scope.versionFilters[originalKey].minorVersion = parsedMinorVersion; + } + } + } + + // Load the search parameter from the URL path + const searchParameter = $location.path().substring(1); // Remove the leading slash + if (searchParameter) { + $scope.search = searchParameter; + $scope.open[searchParameter] = true; + scrollToLintByURL($scope, $location); + } +<<<<<<< HEAD +<<<<<<< HEAD + } + + // updateURLParameter updates the URL parameter with the given key to the given value + function updateURLParameter(filterObj, urlKey, defaultValue = {}, processFilter = filter => filter) { + const parameter = Object.keys(filterObj) + .filter(filter => filterObj[filter]) + .sort() +======= + + // If there are any filters in the URL, mark that the filters have been changed + if (urlParameters.levels || urlParameters.groups || urlParameters.versions) { + $scope.filtersChanged = true; + } +======= +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + } + + // updateURLParameter updates the URL parameter with the given key to the given value + function updateURLParameter(filterObj, urlKey, defaultValue = {}, processFilter = filter => filter) { + const parameter = Object.keys(filterObj) + .filter(filter => filterObj[filter]) +<<<<<<< HEAD +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= + .sort() +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + .map(processFilter) + .filter(Boolean) // Filters out any falsy values, including null + .join(','); + +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + const defaultParameter = Object.keys(defaultValue) + .filter(filter => defaultValue[filter]) + .sort() + .map(processFilter) + .filter(Boolean) // Filters out any falsy values, including null + .join(','); + + // if we ended up back at the defaults, just remove it from the URL + if (parameter === defaultParameter) { + $location.search(urlKey, null); + } else { + $location.search(urlKey, parameter || null); + } +<<<<<<< HEAD +======= + $location.search(urlKey, parameter || null); +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + } + + // updateVersionURLParameter updates the version URL parameter with the given version filters + function updateVersionURLParameter(versionFilters) { + updateURLParameter( + versionFilters, +<<<<<<< HEAD +<<<<<<< HEAD + 'versions', {}, +======= + 'versions', +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= + 'versions', {}, +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + versionFilter => versionFilters[versionFilter].enabled && versionFilters[versionFilter].minorVersion != null + ? `${versionFilterKeyMap[versionFilter]}:${versionFilters[versionFilter].minorVersion}` + : null + ); + } + + // updateAllURLParameters updates all the URL parameters with the current filter settings + function updateAllURLParameters() { +<<<<<<< HEAD +<<<<<<< HEAD + updateURLParameter($scope.levels, 'levels', LEVEL_FILTERS_DEFAULT); + updateURLParameter($scope.groups, 'groups', GROUPS_FILTER_DEFAULT); +======= + updateURLParameter($scope.levels, 'levels'); + updateURLParameter($scope.groups, 'groups'); +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= + updateURLParameter($scope.levels, 'levels', LEVEL_FILTERS_DEFAULT); + updateURLParameter($scope.groups, 'groups', GROUPS_FILTER_DEFAULT); +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + updateVersionURLParameter($scope.versionFilters); + } + + // Add $watches to automatically update URL parameters when the data changes + $scope.$watch('levels', function (newVal, oldVal) { + if (newVal !== oldVal) { +<<<<<<< HEAD +<<<<<<< HEAD + updateURLParameter(newVal, 'levels', LEVEL_FILTERS_DEFAULT); +======= + $scope.filtersChanged = true; + updateURLParameter(newVal, 'levels'); +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= + updateURLParameter(newVal, 'levels', LEVEL_FILTERS_DEFAULT); +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + } + }, true); + + $scope.$watch('groups', function (newVal, oldVal) { + if (newVal !== oldVal) { +<<<<<<< HEAD +<<<<<<< HEAD + updateURLParameter(newVal, 'groups', GROUPS_FILTER_DEFAULT); +======= + $scope.filtersChanged = true; + updateURLParameter(newVal, 'groups'); +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= + updateURLParameter(newVal, 'groups', GROUPS_FILTER_DEFAULT); +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + } + }, true); + + $scope.$watch('versionFilters', function (newVal, oldVal) { + if (newVal !== oldVal) { +<<<<<<< HEAD +<<<<<<< HEAD +======= + $scope.filtersChanged = true; +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + updateVersionURLParameter(newVal); + } + }, true); + +<<<<<<< HEAD +<<<<<<< HEAD + // Watch for changes in the URL path and update the search and lint display + $scope.$watch(function () { return $location.path(); }, function (newPath) { +<<<<<<< HEAD +======= + $scope.$watch('search', function (newVal, oldVal) { + if (newVal !== oldVal) { + $location.path(newVal); + } + }); + +======= +>>>>>>> a865d8432 (Clippy Lints page - Delay updating of the URL in response to search input) + // Watch for changes in the URL path and update the search and lint display +<<<<<<< HEAD + $scope.$watch(function () { + return $location.path(); + }, function (newPath) { +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= + $scope.$watch($location.path, function (newPath) { +>>>>>>> f2e6a99a0 (Clippy Lints page - Do not show groups in URL parameters if reset to defaults) +======= +>>>>>>> 2e4ef8e72 (Clippy Lints page - Fix path watch triggering) + const searchParameter = newPath.substring(1); + if ($scope.search !== searchParameter) { + $scope.search = searchParameter; + $scope.open[searchParameter] = true; + scrollToLintByURL($scope, $location); + } + }); + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> a865d8432 (Clippy Lints page - Delay updating of the URL in response to search input) + let debounceTimeout; + $scope.$watch('search', function (newVal, oldVal) { + if (newVal !== oldVal) { + if (debounceTimeout) { + $timeout.cancel(debounceTimeout); + } + + debounceTimeout = $timeout(function () { + $location.path(newVal); + }, 1000); + } + }); + +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + $scope.$watch(function () { return $location.search(); }, function (newParameters) { + loadFromURLParameters(); +<<<<<<< HEAD + }, true); +======= + $scope.$watch($location.search, function (newParameters) { +======= + $scope.$watch(function () { return $location.search(); }, function (newParameters) { +>>>>>>> 2e4ef8e72 (Clippy Lints page - Fix path watch triggering) + if (!internalURLChange) { + loadFromURLParameters(); + } + internalURLChange = false; +<<<<<<< HEAD + }); +>>>>>>> f2e6a99a0 (Clippy Lints page - Do not show groups in URL parameters if reset to defaults) +======= +======= +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + }, true); +>>>>>>> 2e4ef8e72 (Clippy Lints page - Fix path watch triggering) + + $scope.updatePath = function () { + if (debounceTimeout) { + $timeout.cancel(debounceTimeout); + } + + $location.path($scope.search); + } + +======= +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= +======= +>>>>>>> a865d8432 (Clippy Lints page - Delay updating of the URL in response to search input) + $scope.$watch(function () { + return $location.search(); + }, function (newParameters) { + loadFromURLParameters(); + }); + +<<<<<<< HEAD +>>>>>>> 7c1bca4be (Handle back/forward when using URL parameters for filter states) +======= + $scope.updatePath = function () { + if (debounceTimeout) { + $timeout.cancel(debounceTimeout); + } + + $location.path($scope.search); + } + +>>>>>>> a865d8432 (Clippy Lints page - Delay updating of the URL in response to search input) $scope.selectTheme = function (theme) { setTheme(theme, true); } @@ -169,10 +509,24 @@ }; $scope.resetGroupsToDefault = function () { +<<<<<<< HEAD +<<<<<<< HEAD + $scope.groups = { + ...GROUPS_FILTER_DEFAULT + }; +======= const groups = $scope.groups; for (const [key, value] of Object.entries(GROUPS_FILTER_DEFAULT)) { groups[key] = value; } + internalURLChange = true; + $location.search('groups', null); +>>>>>>> f2e6a99a0 (Clippy Lints page - Do not show groups in URL parameters if reset to defaults) +======= + $scope.groups = { + ...GROUPS_FILTER_DEFAULT + }; +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) }; $scope.selectedValuesCount = function (obj) { @@ -272,6 +626,22 @@ return true; } + // Show details for one lint + $scope.openLint = function (lint) { + $scope.open[lint.id] = true; + $location.path(lint.id); +<<<<<<< HEAD +<<<<<<< HEAD +======= + if ($scope.filtersChanged) { + updateAllURLParameters(); + $scope.filtersChanged = false; + } +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + }; + $scope.copyToClipboard = function (lint) { const clipboard = document.getElementById("clipboard-" + lint.id); if (clipboard) { @@ -296,14 +666,19 @@ // Get data $scope.open = {}; $scope.loading = true; +<<<<<<< HEAD +<<<<<<< HEAD +======= + $scope.filtersChanged = false; +>>>>>>> 5be2b27ed (Use URL parameters for filter states) +======= +>>>>>>> ac279efdb (Clippy Lints page - Do not show filters in URL if configured as default values) + // This will be used to jump into the source code of the version that this documentation is for. $scope.docVersion = window.location.pathname.split('/')[2] || "master"; - if (window.location.hash.length > 1) { - $scope.search = window.location.hash.slice(1); - $scope.open[window.location.hash.slice(1)] = true; - scrollToLintByURL($scope); - } + // Set up the filters from the URL parameters before we start loading the data + loadFromURLParameters(); $http.get('./lints.json') .success(function (data) { @@ -315,7 +690,7 @@ selectGroup($scope, selectedGroup.toLowerCase()); } - scrollToLintByURL($scope); + scrollToLintByURL($scope, $location); setTimeout(function () { var el = document.getElementById('filter-input'); @@ -326,18 +701,6 @@ $scope.error = data; $scope.loading = false; }); - - window.addEventListener('hashchange', function () { - // trigger re-render - $timeout(function () { - $scope.levels = LEVEL_FILTERS_DEFAULT; - $scope.search = window.location.hash.slice(1); - $scope.open[window.location.hash.slice(1)] = true; - - scrollToLintByURL($scope); - }); - return true; - }, false); }); })(); diff --git a/util/gh-pages/versions.html b/util/gh-pages/versions.html index 6e810a349bfc..31ce88193295 100644 --- a/util/gh-pages/versions.html +++ b/util/gh-pages/versions.html @@ -36,7 +36,7 @@

@@ -54,18 +54,15 @@

.controller('docVersions', function ($scope, $http) { $scope.loading = true; - $scope.normalizeVersionDisplay = function(v) { - return v.replace(/^v/, ''); - }; - $scope.normalizeVersion = function(v) { - return v.replace(/^v/, '').replace(/^rust-/, ''); + return v.replace(/^rust-/, ''); }; $scope.versionOrder = function(v) { if (v === 'master') { return Infinity; } if (v === 'stable') { return Number.MAX_VALUE; } if (v === 'beta') { return Number.MAX_VALUE - 1; } + if (v === 'pre-1.29.0') { return Number.MIN_VALUE; } return $scope.normalizeVersion(v) .split('.') diff --git a/util/versions.py b/util/versions.py index 0cfa007d1b27..c041fc606a8f 100755 --- a/util/versions.py +++ b/util/versions.py @@ -1,24 +1,27 @@ #!/usr/bin/env python import json +import logging as log import os import sys -import logging as log -log.basicConfig(level=log.INFO, format='%(levelname)s: %(message)s') + +log.basicConfig(level=log.INFO, format="%(levelname)s: %(message)s") def key(v): - if v == 'master': - return float('inf') - if v == 'stable': + if v == "master": + return float("inf") + if v == "stable": return sys.maxsize - if v == 'beta': + if v == "beta": return sys.maxsize - 1 + if v == "pre-1.29.0": + return -1 - v = v.replace('v', '').replace('rust-', '') + v = v.replace("rust-", "") s = 0 - for i, val in enumerate(v.split('.')[::-1]): + for i, val in enumerate(v.split(".")[::-1]): s += int(val) * 100**i return s @@ -31,7 +34,11 @@ def main(): outdir = sys.argv[1] versions = [ - dir for dir in os.listdir(outdir) if not dir.startswith(".") and os.path.isdir(os.path.join(outdir, dir)) + dir + for dir in os.listdir(outdir) + if not dir.startswith(".") + and not dir.startswith("v") + and os.path.isdir(os.path.join(outdir, dir)) ] versions.sort(key=key)