Fix false-positive in expr_or_init and in the invalid_from_utf8 lint

This commit is contained in:
Urgau 2025-03-09 18:49:59 +01:00
parent 3ea711f17e
commit faa5b3f7de
3 changed files with 58 additions and 64 deletions

View file

@ -6,6 +6,7 @@
use std::cell::Cell;
use std::slice;
use rustc_ast::BindingMode;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync;
use rustc_data_structures::unord::UnordMap;
@ -14,6 +15,7 @@ use rustc_feature::Features;
use rustc_hir::def::Res;
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_hir::{Pat, PatKind};
use rustc_middle::bug;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
@ -890,7 +892,12 @@ impl<'tcx> LateContext<'tcx> {
}
&& let Some(init) = match parent_node {
hir::Node::Expr(expr) => Some(expr),
hir::Node::LetStmt(hir::LetStmt { init, .. }) => *init,
hir::Node::LetStmt(hir::LetStmt {
init,
// Binding is immutable, init cannot be re-assigned
pat: Pat { kind: PatKind::Binding(BindingMode::NONE, ..), .. },
..
}) => *init,
_ => None,
}
{
@ -935,7 +942,12 @@ impl<'tcx> LateContext<'tcx> {
}
&& let Some(init) = match parent_node {
hir::Node::Expr(expr) => Some(expr),
hir::Node::LetStmt(hir::LetStmt { init, .. }) => *init,
hir::Node::LetStmt(hir::LetStmt {
init,
// Binding is immutable, init cannot be re-assigned
pat: Pat { kind: PatKind::Binding(BindingMode::NONE, ..), .. },
..
}) => *init,
hir::Node::Item(item) => match item.kind {
hir::ItemKind::Const(.., body_id) | hir::ItemKind::Static(.., body_id) => {
Some(self.tcx.hir_body(body_id).value)

View file

@ -128,18 +128,21 @@ pub fn from_utf8() {
}
pub fn from_utf8_with_indirections() {
let mut a = [99, 108, 130, 105, 112, 112, 121];
std::str::from_utf8_mut(&mut a);
//~^ WARN calls to `std::str::from_utf8_mut`
str::from_utf8_mut(&mut a);
//~^ WARN calls to `str::from_utf8_mut`
let mut b = &mut a;
let mut c = b;
std::str::from_utf8_mut(c);
//~^ WARN calls to `std::str::from_utf8_mut`
str::from_utf8_mut(c);
//~^ WARN calls to `str::from_utf8_mut`
let mut c = &[99, 108, 130, 105, 112, 112, 121];
// NOTE: We used to lint on the patterns below, but due to the
// binding being mutable it could be changed between the
// declaration and the call and that would have created a
// false-positive, so until we can reliably avoid those false
// postive we don't lint on them. Example of FP below.
//
// let mut a = [99, 108, 130, 105, 112, 112, 121];
// std::str::from_utf8_mut(&mut a);
// str::from_utf8_mut(&mut a);
// let mut b = &mut a;
// let mut c = b;
// std::str::from_utf8_mut(c);
// str::from_utf8_mut(c);
let c = &[99, 108, 130, 105, 112, 112, 121];
std::str::from_utf8(c);
//~^ WARN calls to `std::str::from_utf8`
str::from_utf8(c);
@ -164,6 +167,20 @@ pub fn from_utf8_with_indirections() {
//~^ WARN calls to `std::str::from_utf8`
str::from_utf8(INVALID_4);
//~^ WARN calls to `str::from_utf8`
let mut a = [99, 108, 130, 105, 112, 112, 121]; // invalid
loop {
a = [99, 108, 130, 105, 112, 112, 121]; // still invalid, but too complex
break;
}
std::str::from_utf8_mut(&mut a);
let mut a = [99, 108, 130, 105, 112, 112]; // invalid
loop {
a = *b"clippy"; // valid
break;
}
std::str::from_utf8_mut(&mut a);
}
fn main() {}

View file

@ -202,60 +202,25 @@ LL | str::from_utf8(concat_bytes!(b"cl", b"\x82ippy"));
| |
| the literal was valid UTF-8 up to the 2 bytes
warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:132:5
|
LL | let mut a = [99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
LL | std::str::from_utf8_mut(&mut a);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: calls to `str::from_utf8_mut` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:134:5
|
LL | let mut a = [99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
...
LL | str::from_utf8_mut(&mut a);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:138:5
|
LL | let mut a = [99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
...
LL | std::str::from_utf8_mut(c);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: calls to `str::from_utf8_mut` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:140:5
|
LL | let mut a = [99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
...
LL | str::from_utf8_mut(c);
| ^^^^^^^^^^^^^^^^^^^^^
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:143:5
--> $DIR/invalid_from_utf8.rs:146:5
|
LL | let mut c = &[99, 108, 130, 105, 112, 112, 121];
LL | let c = &[99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
LL | std::str::from_utf8(c);
| ^^^^^^^^^^^^^^^^^^^^^^
warning: calls to `str::from_utf8` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:145:5
--> $DIR/invalid_from_utf8.rs:148:5
|
LL | let mut c = &[99, 108, 130, 105, 112, 112, 121];
LL | let c = &[99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
...
LL | str::from_utf8(c);
| ^^^^^^^^^^^^^^^^^
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:148:5
--> $DIR/invalid_from_utf8.rs:151:5
|
LL | const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
@ -263,7 +228,7 @@ LL | std::str::from_utf8(&INVALID_1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: calls to `str::from_utf8` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:150:5
--> $DIR/invalid_from_utf8.rs:153:5
|
LL | const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
@ -272,7 +237,7 @@ LL | str::from_utf8(&INVALID_1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:153:5
--> $DIR/invalid_from_utf8.rs:156:5
|
LL | static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
@ -280,7 +245,7 @@ LL | std::str::from_utf8(&INVALID_2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: calls to `str::from_utf8` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:155:5
--> $DIR/invalid_from_utf8.rs:158:5
|
LL | static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
@ -289,7 +254,7 @@ LL | str::from_utf8(&INVALID_2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:158:5
--> $DIR/invalid_from_utf8.rs:161:5
|
LL | const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
@ -297,7 +262,7 @@ LL | std::str::from_utf8(INVALID_3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: calls to `str::from_utf8` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:160:5
--> $DIR/invalid_from_utf8.rs:163:5
|
LL | const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121];
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
@ -306,7 +271,7 @@ LL | str::from_utf8(INVALID_3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:163:5
--> $DIR/invalid_from_utf8.rs:166:5
|
LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] };
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
@ -314,7 +279,7 @@ LL | std::str::from_utf8(INVALID_4);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: calls to `str::from_utf8` with an invalid literal always return an error
--> $DIR/invalid_from_utf8.rs:165:5
--> $DIR/invalid_from_utf8.rs:168:5
|
LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] };
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
@ -322,5 +287,5 @@ LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 12
LL | str::from_utf8(INVALID_4);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: 38 warnings emitted
warning: 34 warnings emitted