Skip to content

Update Clippy #94929

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 97 commits into from
Mar 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
a71f199
Updated styles for checkboxes
CrazyRoka Dec 3, 2021
0f655db
Added badge to display selected elemenets count
CrazyRoka Dec 4, 2021
cb113d3
Updated badge
CrazyRoka Dec 5, 2021
f71039a
Fixed styles on all themes
CrazyRoka Dec 5, 2021
e895d2b
Fixed error in Firefox and selected button style
CrazyRoka Dec 6, 2021
76e95e2
Fixed theme selector and repositioned search input
CrazyRoka Dec 6, 2021
dcfb756
Fixed overlapping "Fork me" logo
CrazyRoka Dec 7, 2021
bb53132
Improved performance by adding ng-if
CrazyRoka Dec 7, 2021
4161a67
Added dropdown directive to theme-selector
CrazyRoka Dec 9, 2021
296af08
Removed unused styles and labels in dropdowns
CrazyRoka Dec 16, 2021
6daa6d5
Optimize redundant_clone
MiSawa Feb 11, 2022
4f96ca3
add only_used_in_recursion lint
buttercrab Feb 12, 2022
9055f34
Merge remote-tracking branch 'upstream/master' into only_used_in_recu…
buttercrab Feb 12, 2022
3a090c9
Merge remote-tracking branch 'upstream/master' into only_used_in_recu…
buttercrab Feb 12, 2022
8faa938
fix only_used_in_recursion not to lint when unused_variable
buttercrab Feb 12, 2022
124bb03
changed algorithm
buttercrab Feb 12, 2022
1a69b17
fix parameters applying lint
buttercrab Feb 12, 2022
2b3e7fa
add description
buttercrab Feb 12, 2022
2ebe751
add documentation
buttercrab Feb 13, 2022
48d310e
add documentation
buttercrab Feb 13, 2022
fd9dd04
Transmute_undefined_repr to nursery again
dtolnay Feb 12, 2022
7412e69
Use the precise namespace for `Reverse`
ken-matsui Feb 22, 2022
6d2a042
Don't assume DAG
MiSawa Feb 23, 2022
88483bd
Replace `&mut DiagnosticBuilder`, in signatures, with `&mut Diagnostic`.
eddyb Jan 23, 2022
881b8cb
rustc_errors: take `self` by value in `DiagnosticBuilder::cancel`.
eddyb Jan 26, 2022
676943a
better ObligationCause for normalization errors in can_type_implement…
compiler-errors Feb 6, 2022
83d3270
resolve: Fix incorrect results of `opt_def_kind` query for some built…
petrochenkov Dec 11, 2021
a30eba2
Update clippy tests
petrochenkov Feb 5, 2022
996fa50
Rollup merge of #93714 - compiler-errors:can-type-impl-copy-error-spa…
Dylan-DPC Feb 24, 2022
87355df
Auto merge of #93368 - eddyb:diagbld-guarantee, r=estebank
bors Feb 25, 2022
30fb822
add tests, add base bone for the new lint
J-ZhengLi Feb 25, 2022
307966f
Switch bootstrap cfgs
Mark-Simulacrum Feb 23, 2022
3502028
Merge commit 'e329249b6a3a98830d860c74c8234a8dd9407436' into clippyup
flip1995 Feb 26, 2022
d1ca1c1
Auto merge of #8462 - ken-matsui:use-precise-namespace-for-reverse, r…
bors Feb 26, 2022
914ae1e
check `use_self` in `pat`
ebobrow Feb 21, 2022
acddac4
Update edition in rustfmt.toml
xFrednet Feb 26, 2022
8d12cd4
Auto merge of #8476 - xFrednet:0000-update-edition-for-rustfmt, r=gir…
bors Feb 27, 2022
cfd3252
Add tests to tests/ui/unnecessary_filter_map.rs
smoelius Feb 28, 2022
d123ffc
Check `clone_or_copy_needed` in `unnecessary_filter_map::check`
smoelius Feb 28, 2022
e511476
Auto merge of #8479 - smoelius:unnecessary-filter-map, r=llogiq
bors Feb 28, 2022
bca4ee7
Implement internal lint for MSRV lints
flip1995 Jan 19, 2022
7394464
Move testing of cargo dev new_lint to cargo dev workflow
flip1995 Mar 1, 2022
28b1fe5
Auto merge of #8313 - flip1995:msrv-internal-lint, r=xFrednet
bors Mar 1, 2022
b8a205a
Auto merge of #8488 - flip1995:ci-cargo-dev-new-lint, r=llogiq
bors Mar 1, 2022
7a15061
tests: use std::thread::available_parallelism() instead of num_cpus t…
matthiaskrgr Mar 1, 2022
2a588d8
Add `unnecessary_find_map` lint
smoelius Mar 1, 2022
1a25d19
Auto merge of #8491 - matthiaskrgr:no_num_cpus, r=flip1995
bors Mar 2, 2022
14f3d05
Auto merge of #8432 - dtolnay-contrib:transmuteundefinedrepr2, r=Mani…
bors Mar 2, 2022
9f1080c
new lint: `missing-spin-loop`
llogiq Dec 26, 2021
27869d6
Auto merge of #8174 - rust-lang:missing-spin-loop, r=flip1995
bors Mar 2, 2022
2e40dc8
Auto merge of #8456 - ebobrow:use_self_pat, r=llogiq
bors Mar 2, 2022
6e211ea
Auto merge of #8489 - smoelius:unnecessary-find-map, r=llogiq
bors Mar 2, 2022
7f44a75
Move transmute_undefined_repr back to nursery
flip1995 Feb 15, 2022
c45a42a
bless clippy
RalfJung Mar 3, 2022
6cc2eea
Suggest `into_iter()` over `drain(..)`
ldm0 Feb 12, 2022
78547b1
comment about transmute_undefined_repr in nursery
Manishearth Mar 2, 2022
ef4af1d
Auto merge of #8497 - Manishearth:transmute-undefined-repr-note, r=fl…
bors Mar 3, 2022
92b6955
Auto merge of #94512 - RalfJung:sdiv-ub, r=oli-obk
bors Mar 3, 2022
d56f457
Auto merge of #8483 - ldm0:iter_with_drain_simple, r=flip1995,giraffate
bors Mar 3, 2022
c5faf99
Auto merge of #8414 - MiSawa:fix/optimize-redundant-clone, r=oli-obk
bors Mar 3, 2022
6390723
Omit dbg_macro in test code
llogiq Mar 3, 2022
53189ad
Auto merge of #8500 - rust-lang:testless-dbg-macro, r=Manishearth
bors Mar 3, 2022
ab6ffb6
Add lint to detect `allow` attributes without reason
xFrednet Mar 3, 2022
c8d6a55
Update `itertools`
pierwill Mar 4, 2022
f932c30
lint for casting raw pointers to slices with different element sizes
asquared31415 Feb 18, 2022
48d5494
Auto merge of #8504 - xFrednet:8502-allow-lint-without-reason, r=flip…
bors Mar 4, 2022
90da7cd
Do not point at whole file missing `fn main`
estebank Jan 21, 2022
2b0f9ab
don't lint when implementing trait
buttercrab Mar 5, 2022
c4a3ccd
fix lint errors
buttercrab Mar 5, 2022
9bee01e
Change syntax for TyAlias where clauses
jackh726 Oct 19, 2021
0c483f6
Auto merge of #8445 - asquared31415:slice_ptr_cast, r=llogiq
bors Mar 6, 2022
dcc6ecf
Rollup merge of #94617 - pierwill:update-itertools, r=Mark-Simulacrum
matthiaskrgr Mar 6, 2022
96eb116
Introduce `ConstAllocation`.
nnethercote Mar 1, 2022
b36924b
Clarify `Layout` interning.
nnethercote Mar 4, 2022
e476677
add test for trait recursion
buttercrab Mar 7, 2022
db3fcf8
add basic code to check nop match blocks
J-ZhengLi Mar 7, 2022
b86620d
Stabilize const_fn_fn_ptr_basics and const_fn_trait_bound
eholk Feb 9, 2022
43ce0a9
Update and fix clippy tests
eholk Feb 11, 2022
d3bc129
Auto merge of #94706 - matthiaskrgr:rollup-l5erynr, r=matthiaskrgr
bors Mar 7, 2022
6bfc112
add nop if-let expression check.
J-ZhengLi Mar 8, 2022
750204e
fix a bug that caused internal test fail
J-ZhengLi Mar 8, 2022
a4d6c61
add `#[rustc_pass_by_value]` to more types
lcnr Mar 8, 2022
ec91164
rename lint to `needless_match`
J-ZhengLi Mar 10, 2022
8ae74da
Auto merge of #8070 - CrazyRoka:update-gh-pages-checkbox-styles, r=ca…
bors Mar 10, 2022
69161c6
fix to lint Self::function
buttercrab Mar 10, 2022
086b045
add checking for `x -> x` and `ref x -> x` and related test cases.
J-ZhengLi Mar 10, 2022
52d35dc
fix build error
buttercrab Mar 10, 2022
1ad7e70
remove parameters that are only used in recursion
buttercrab Mar 10, 2022
e110231
Improve `AdtDef` interning.
nnethercote Mar 4, 2022
75b616e
Auto merge of #8471 - J-ZhengLi:master-issue7040, r=llogiq
bors Mar 13, 2022
800f66d
add clearing return vars
buttercrab Mar 13, 2022
e2e492c
Auto merge of #8422 - buttercrab:only_used_in_recursion, r=llogiq
bors Mar 13, 2022
d5ab347
Merge remote-tracking branch 'upstream/master' into rustup
flip1995 Mar 14, 2022
2ebd0b2
Bump nightly version -> 2022-03-14
flip1995 Mar 14, 2022
dc5423a
Auto merge of #8534 - flip1995:rustup, r=flip1995
bors Mar 14, 2022
3585e1c
Merge commit 'dc5423ad448877e33cca28db2f1445c9c4473c75' into clippyup
flip1995 Mar 14, 2022
706fa54
Update Cargo.lock
flip1995 Mar 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -624,10 +624,10 @@ dependencies = [
"futures 0.3.19",
"if_chain",
"itertools",
"num_cpus",
"parking_lot",
"quote",
"regex",
"rustc-semver",
"rustc-workspace-hack",
"rustc_tools_util 0.2.0",
"semver",
Expand Down
7 changes: 0 additions & 7 deletions src/tools/clippy/.github/workflows/clippy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,3 @@ jobs:
run: bash .github/driver.sh
env:
OS: ${{ runner.os }}

- name: Test cargo dev new lint
run: |
cargo dev new_lint --name new_early_pass --pass early
cargo dev new_lint --name new_late_pass --pass late
cargo check
git reset --hard HEAD
7 changes: 0 additions & 7 deletions src/tools/clippy/.github/workflows/clippy_bors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,6 @@ jobs:
env:
OS: ${{ runner.os }}

- name: Test cargo dev new lint
run: |
cargo dev new_lint --name new_early_pass --pass early
cargo dev new_lint --name new_late_pass --pass late
cargo check
git reset --hard HEAD

integration_build:
needs: changelog
runs-on: ubuntu-latest
Expand Down
7 changes: 7 additions & 0 deletions src/tools/clippy/.github/workflows/clippy_dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ jobs:
- name: Test fmt
run: cargo dev fmt --check

- name: Test cargo dev new lint
run: |
cargo dev new_lint --name new_early_pass --pass early
cargo dev new_lint --name new_late_pass --pass late
cargo check
git reset --hard HEAD

# These jobs doesn't actually test anything, but they're only used to tell
# bors the build completed, as there is no practical way to detect when a
# workflow is successful listening to webhooks only.
Expand Down
7 changes: 7 additions & 0 deletions src/tools/clippy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3042,6 +3042,7 @@ Released 2018-09-13
<!-- lint disable no-unused-definitions -->
<!-- begin autogenerated links to lint list -->
[`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons
[`allow_attributes_without_reason`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes_without_reason
[`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
[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
Expand Down Expand Up @@ -3076,6 +3077,7 @@ Released 2018-09-13
[`cast_ptr_alignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_ptr_alignment
[`cast_ref_to_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_ref_to_mut
[`cast_sign_loss`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_sign_loss
[`cast_slice_different_sizes`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_slice_different_sizes
[`char_lit_as_u8`]: https://rust-lang.github.io/rust-clippy/master/index.html#char_lit_as_u8
[`chars_last_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#chars_last_cmp
[`chars_next_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#chars_next_cmp
Expand Down Expand Up @@ -3225,6 +3227,7 @@ Released 2018-09-13
[`iter_nth_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth_zero
[`iter_overeager_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_overeager_cloned
[`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
[`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
Expand Down Expand Up @@ -3297,6 +3300,7 @@ Released 2018-09-13
[`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
[`missing_spin_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_spin_loop
[`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
[`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_case_hex_literals
[`mod_module_files`]: https://rust-lang.github.io/rust-clippy/master/index.html#mod_module_files
Expand Down Expand Up @@ -3327,6 +3331,7 @@ Released 2018-09-13
[`needless_for_each`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_for_each
[`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_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
[`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark
Expand All @@ -3351,6 +3356,7 @@ Released 2018-09-13
[`not_unsafe_ptr_arg_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#not_unsafe_ptr_arg_deref
[`octal_escapes`]: https://rust-lang.github.io/rust-clippy/master/index.html#octal_escapes
[`ok_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#ok_expect
[`only_used_in_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#only_used_in_recursion
[`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref
[`option_as_ref_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref
[`option_env_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_env_unwrap
Expand Down Expand Up @@ -3498,6 +3504,7 @@ Released 2018-09-13
[`unit_return_expecting_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_return_expecting_ord
[`unnecessary_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast
[`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_filter_map
[`unnecessary_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_find_map
[`unnecessary_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fold
[`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations
[`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ syn = { version = "1.0", features = ["full"] }
futures = "0.3"
parking_lot = "0.11.2"
tokio = { version = "1", features = ["io-util"] }
num_cpus = "1.13"
rustc-semver = "1.1"

[build-dependencies]
rustc_tools_util = { version = "0.2", path = "rustc_tools_util" }
Expand Down
60 changes: 59 additions & 1 deletion src/tools/clippy/clippy_lints/src/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,38 @@ declare_clippy_lint! {
"usage of `cfg(operating_system)` instead of `cfg(target_os = \"operating_system\")`"
}

declare_clippy_lint! {
/// ### What it does
/// Checks for attributes that allow lints without a reason.
///
/// (This requires the `lint_reasons` feature)
///
/// ### Why is this bad?
/// Allowing a lint should always have a reason. This reason should be documented to
/// ensure that others understand the reasoning
///
/// ### Example
/// Bad:
/// ```rust
/// #![feature(lint_reasons)]
///
/// #![allow(clippy::some_lint)]
/// ```
///
/// Good:
/// ```rust
/// #![feature(lint_reasons)]
///
/// #![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
/// ```
#[clippy::version = "1.61.0"]
pub ALLOW_ATTRIBUTES_WITHOUT_REASON,
restriction,
"ensures that all `allow` and `expect` attributes have a reason"
}

declare_lint_pass!(Attributes => [
ALLOW_ATTRIBUTES_WITHOUT_REASON,
INLINE_ALWAYS,
DEPRECATED_SEMVER,
USELESS_ATTRIBUTE,
Expand All @@ -269,6 +300,9 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
if is_lint_level(ident.name) {
check_clippy_lint_names(cx, ident.name, items);
}
if matches!(ident.name, sym::allow | sym::expect) {
check_lint_reason(cx, ident.name, items, attr);
}
if items.is_empty() || !attr.has_name(sym::deprecated) {
return;
}
Expand Down Expand Up @@ -404,6 +438,30 @@ fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMe
}
}

fn check_lint_reason(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem], attr: &'_ Attribute) {
// Check for the feature
if !cx.tcx.sess.features_untracked().lint_reasons {
return;
}

// Check if the reason is present
if let Some(item) = items.last().and_then(NestedMetaItem::meta_item)
&& let MetaItemKind::NameValue(_) = &item.kind
&& item.path == sym::reason
{
return;
}

span_lint_and_help(
cx,
ALLOW_ATTRIBUTES_WITHOUT_REASON,
attr.span,
&format!("`{}` attribute without specifying a reason", name.as_str()),
None,
"try adding a reason at the end with `, reason = \"..\"`",
);
}

fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
if let ItemKind::Fn(_, _, eid) = item.kind {
is_relevant_expr(cx, cx.tcx.typeck_body(eid), &cx.tcx.hir().body(eid).value)
Expand Down Expand Up @@ -659,5 +717,5 @@ fn check_mismatched_target_os(cx: &EarlyContext<'_>, attr: &Attribute) {
}

fn is_lint_level(symbol: Symbol) -> bool {
matches!(symbol, sym::allow | sym::warn | sym::deny | sym::forbid)
matches!(symbol, sym::allow | sym::expect | sym::warn | sym::deny | sym::forbid)
}
117 changes: 117 additions & 0 deletions src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use clippy_utils::{diagnostics::span_lint_and_then, meets_msrv, msrvs, source::snippet_opt};
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_semver::RustcVersion;

use super::CAST_SLICE_DIFFERENT_SIZES;

fn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
let map = cx.tcx.hir();
if_chain! {
if let Some(parent_id) = map.find_parent_node(expr.hir_id);
if let Some(parent) = map.find(parent_id);
then {
let expr = match parent {
Node::Block(block) => {
if let Some(parent_expr) = block.expr {
parent_expr
} else {
return false;
}
},
Node::Expr(expr) => expr,
_ => return false,
};

matches!(expr.kind, ExprKind::Cast(..))
} else {
false
}
}
}

pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Option<RustcVersion>) {
// suggestion is invalid if `ptr::slice_from_raw_parts` does not exist
if !meets_msrv(msrv.as_ref(), &msrvs::PTR_SLICE_RAW_PARTS) {
return;
}

// if this cast is the child of another cast expression then don't emit something for it, the full
// chain will be analyzed
if is_child_of_cast(cx, expr) {
return;
}

if let Some((from_slice_ty, to_slice_ty)) = expr_cast_chain_tys(cx, expr) {
if let (Ok(from_layout), Ok(to_layout)) = (cx.layout_of(from_slice_ty.ty), cx.layout_of(to_slice_ty.ty)) {
let from_size = from_layout.size.bytes();
let to_size = to_layout.size.bytes();
if from_size != to_size && from_size != 0 && to_size != 0 {
span_lint_and_then(
cx,
CAST_SLICE_DIFFERENT_SIZES,
expr.span,
&format!(
"casting between raw pointers to `[{}]` (element size {}) and `[{}]` (element size {}) does not adjust the count",
from_slice_ty, from_size, to_slice_ty, to_size,
),
|diag| {
let cast_expr = match expr.kind {
ExprKind::Cast(cast_expr, ..) => cast_expr,
_ => unreachable!("expr should be a cast as checked by expr_cast_chain_tys"),
};
let ptr_snippet = snippet_opt(cx, cast_expr.span).unwrap();

let (mutbl_fn_str, mutbl_ptr_str) = match to_slice_ty.mutbl {
Mutability::Mut => ("_mut", "mut"),
Mutability::Not => ("", "const"),
};
let sugg = format!(
"core::ptr::slice_from_raw_parts{mutbl_fn_str}({ptr_snippet} as *{mutbl_ptr_str} {to_slice_ty}, ..)"
);

diag.span_suggestion(
expr.span,
&format!("replace with `ptr::slice_from_raw_parts{mutbl_fn_str}`"),
sugg,
rustc_errors::Applicability::HasPlaceholders,
);
},
);
}
}
}
}

/// Returns the type T of the pointed to *const [T] or *mut [T] and the mutability of the slice if
/// the type is one of those slices
fn get_raw_slice_ty_mut(ty: Ty<'_>) -> Option<TypeAndMut<'_>> {
match ty.kind() {
ty::RawPtr(TypeAndMut { ty: slice_ty, mutbl }) => match slice_ty.kind() {
ty::Slice(ty) => Some(TypeAndMut { ty: *ty, mutbl: *mutbl }),
_ => None,
},
_ => None,
}
}

/// Returns the pair (original ptr T, final ptr U) if the expression is composed of casts
/// Returns None if the expr is not a Cast
fn expr_cast_chain_tys<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<(TypeAndMut<'tcx>, TypeAndMut<'tcx>)> {
if let ExprKind::Cast(cast_expr, _cast_to_hir_ty) = expr.peel_blocks().kind {
let cast_to = cx.typeck_results().expr_ty(expr);
let to_slice_ty = get_raw_slice_ty_mut(cast_to)?;
if let Some((inner_from_ty, _inner_to_ty)) = expr_cast_chain_tys(cx, cast_expr) {
Some((inner_from_ty, to_slice_ty))
} else {
let cast_from = cx.typeck_results().expr_ty(cast_expr);
let from_slice_ty = get_raw_slice_ty_mut(cast_from)?;
Some((from_slice_ty, to_slice_ty))
}
} else {
None
}
}
48 changes: 48 additions & 0 deletions src/tools/clippy/clippy_lints/src/casts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod cast_precision_loss;
mod cast_ptr_alignment;
mod cast_ref_to_mut;
mod cast_sign_loss;
mod cast_slice_different_sizes;
mod char_lit_as_u8;
mod fn_to_numeric_cast;
mod fn_to_numeric_cast_any;
Expand Down Expand Up @@ -409,6 +410,50 @@ declare_clippy_lint! {
"casts from an enum type to an integral type which will truncate the value"
}

declare_clippy_lint! {
/// Checks for `as` casts between raw pointers to slices with differently sized elements.
///
/// ### Why is this bad?
/// The produced raw pointer to a slice does not update its length metadata. The produced
/// pointer will point to a different number of bytes than the original pointer because the
/// length metadata of a raw slice pointer is in elements rather than bytes.
/// Producing a slice reference from the raw pointer will either create a slice with
/// less data (which can be surprising) or create a slice with more data and cause Undefined Behavior.
///
/// ### Example
/// // Missing data
/// ```rust
/// let a = [1_i32, 2, 3, 4];
/// let p = &a as *const [i32] as *const [u8];
/// unsafe {
/// println!("{:?}", &*p);
/// }
/// ```
/// // Undefined Behavior (note: also potential alignment issues)
/// ```rust
/// let a = [1_u8, 2, 3, 4];
/// let p = &a as *const [u8] as *const [u32];
/// unsafe {
/// println!("{:?}", &*p);
/// }
/// ```
/// Instead use `ptr::slice_from_raw_parts` to construct a slice from a data pointer and the correct length
/// ```rust
/// let a = [1_i32, 2, 3, 4];
/// let old_ptr = &a as *const [i32];
/// // The data pointer is cast to a pointer to the target `u8` not `[u8]`
/// // The length comes from the known length of 4 i32s times the 4 bytes per i32
/// let new_ptr = core::ptr::slice_from_raw_parts(old_ptr as *const u8, 16);
/// unsafe {
/// println!("{:?}", &*new_ptr);
/// }
/// ```
#[clippy::version = "1.60.0"]
pub CAST_SLICE_DIFFERENT_SIZES,
correctness,
"casting using `as` between raw pointers to slices of types with different sizes"
}

pub struct Casts {
msrv: Option<RustcVersion>,
}
Expand All @@ -428,6 +473,7 @@ impl_lint_pass!(Casts => [
CAST_LOSSLESS,
CAST_REF_TO_MUT,
CAST_PTR_ALIGNMENT,
CAST_SLICE_DIFFERENT_SIZES,
UNNECESSARY_CAST,
FN_TO_NUMERIC_CAST_ANY,
FN_TO_NUMERIC_CAST,
Expand Down Expand Up @@ -478,6 +524,8 @@ 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);
cast_slice_different_sizes::check(cx, expr, &self.msrv);
}

extract_msrv_attr!(LateContext);
Expand Down
Loading