-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #9995
- Loading branch information
Showing
6 changed files
with
131 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
use clippy_utils::{diagnostics::span_lint_and_help, path_def_id, ty::peel_mid_ty_refs}; | ||
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 calls to `std::mem::size_of_val()` where the argument is | ||
/// a reference to a reference. | ||
/// | ||
/// ### Why is this bad? | ||
/// | ||
/// Calling `size_of_val()` with a reference to a reference as the argument | ||
/// yields the size of the reference-type, not the size of the value behind | ||
/// the reference. | ||
/// | ||
/// ### Example | ||
/// ```rust | ||
/// struct Foo { | ||
/// buffer: [u8], | ||
/// } | ||
/// | ||
/// impl Foo { | ||
/// fn size(&self) -> usize { | ||
/// // Note that `&self` as an argument is a `&&Foo`: Because `self` | ||
/// // is already a reference, `&self` is a double-reference. | ||
/// // The return value of `size_of_val()` therefor is the | ||
/// // size of the reference-type, not the size of `self`. | ||
/// std::mem::size_of_val(&self) | ||
/// } | ||
/// } | ||
/// ``` | ||
/// Use instead: | ||
/// ```rust | ||
/// struct Foo { | ||
/// buffer: [u8], | ||
/// } | ||
/// | ||
/// impl Foo { | ||
/// fn size(&self) -> usize { | ||
/// // Correct | ||
/// std::mem::size_of_val(self) | ||
/// } | ||
/// } | ||
/// ``` | ||
#[clippy::version = "1.67.0"] | ||
pub SIZE_OF_REF, | ||
suspicious, | ||
"Argument to `std::mem::size_of_val()` is a double-reference, which is almost certainly unintended" | ||
} | ||
declare_lint_pass!(SizeOfRef => [SIZE_OF_REF]); | ||
|
||
impl LateLintPass<'_> for SizeOfRef { | ||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) { | ||
if let ExprKind::Call(path, [arg]) = expr.kind | ||
&& let Some(def_id) = path_def_id(cx, path) | ||
&& cx.tcx.is_diagnostic_item(sym::mem_size_of_val, def_id) | ||
&& let arg_ty = cx.typeck_results().expr_ty(arg) | ||
&& peel_mid_ty_refs(arg_ty).1 > 1 | ||
{ | ||
span_lint_and_help( | ||
cx, | ||
SIZE_OF_REF, | ||
expr.span, | ||
"argument to `std::mem::size_of_val()` is a reference to a reference", | ||
None, | ||
"dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type", | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#![allow(unused)] | ||
#![warn(clippy::size_of_ref)] | ||
|
||
use std::mem::size_of_val; | ||
|
||
fn main() { | ||
let x = 5; | ||
let y = &x; | ||
|
||
size_of_val(&x); // no lint | ||
size_of_val(y); // no lint | ||
|
||
size_of_val(&&x); | ||
size_of_val(&y); | ||
} | ||
|
||
struct S { | ||
field: u32, | ||
data: Vec<u8>, | ||
} | ||
|
||
impl S { | ||
/// Get size of object including `self`, in bytes. | ||
pub fn size(&self) -> usize { | ||
std::mem::size_of_val(&self) + (std::mem::size_of::<u8>() * self.data.capacity()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
error: argument to `std::mem::size_of_val()` is a reference to a reference | ||
--> $DIR/size_of_ref.rs:13:5 | ||
| | ||
LL | size_of_val(&&x); | ||
| ^^^^^^^^^^^^^^^^ | ||
| | ||
= help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type | ||
= note: `-D clippy::size-of-ref` implied by `-D warnings` | ||
|
||
error: argument to `std::mem::size_of_val()` is a reference to a reference | ||
--> $DIR/size_of_ref.rs:14:5 | ||
| | ||
LL | size_of_val(&y); | ||
| ^^^^^^^^^^^^^^^ | ||
| | ||
= help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type | ||
|
||
error: argument to `std::mem::size_of_val()` is a reference to a reference | ||
--> $DIR/size_of_ref.rs:25:9 | ||
| | ||
LL | std::mem::size_of_val(&self) + (std::mem::size_of::<u8>() * self.data.capacity()) | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type | ||
|
||
error: aborting due to 3 previous errors | ||
|