Skip to content

Commit f53d0f5

Browse files
committed
invalid_from_utf8[_unchecked]: also lint inherent methods
1 parent 4229b80 commit f53d0f5

File tree

6 files changed

+269
-43
lines changed

6 files changed

+269
-43
lines changed

compiler/rustc_lint/messages.ftl

+2-2
Original file line numberDiff line numberDiff line change
@@ -439,11 +439,11 @@ lint_invalid_crate_type_value = invalid `crate_type` value
439439
.suggestion = did you mean
440440
441441
# FIXME: we should ordinalize $valid_up_to when we add support for doing so
442-
lint_invalid_from_utf8_checked = calls to `{$method}` with a invalid literal always return an error
442+
lint_invalid_from_utf8_checked = calls to `{$method}` with an invalid literal always return an error
443443
.label = the literal was valid UTF-8 up to the {$valid_up_to} bytes
444444
445445
# FIXME: we should ordinalize $valid_up_to when we add support for doing so
446-
lint_invalid_from_utf8_unchecked = calls to `{$method}` with a invalid literal are undefined behavior
446+
lint_invalid_from_utf8_unchecked = calls to `{$method}` with an invalid literal are undefined behavior
447447
.label = the literal was valid UTF-8 up to the {$valid_up_to} bytes
448448
449449
lint_invalid_nan_comparisons_eq_ne = incorrect NaN comparison, NaN cannot be directly compared to itself

compiler/rustc_lint/src/invalid_from_utf8.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,20 @@ impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 {
7070
sym::str_from_utf8_mut,
7171
sym::str_from_utf8_unchecked,
7272
sym::str_from_utf8_unchecked_mut,
73+
sym::str_inherent_from_utf8,
74+
sym::str_inherent_from_utf8_mut,
75+
sym::str_inherent_from_utf8_unchecked,
76+
sym::str_inherent_from_utf8_unchecked_mut,
7377
]
7478
.contains(&diag_item)
7579
{
7680
let lint = |label, utf8_error: Utf8Error| {
7781
let method = diag_item.as_str().strip_prefix("str_").unwrap();
78-
let method = format!("std::str::{method}");
82+
let method = if let Some(method) = method.strip_prefix("inherent_") {
83+
format!("str::{method}")
84+
} else {
85+
format!("std::str::{method}")
86+
};
7987
let valid_up_to = utf8_error.valid_up_to();
8088
let is_unchecked_variant = diag_item.as_str().contains("unchecked");
8189

compiler/rustc_span/src/symbol.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1973,6 +1973,10 @@ symbols! {
19731973
str_from_utf8_mut,
19741974
str_from_utf8_unchecked,
19751975
str_from_utf8_unchecked_mut,
1976+
str_inherent_from_utf8,
1977+
str_inherent_from_utf8_mut,
1978+
str_inherent_from_utf8_unchecked,
1979+
str_inherent_from_utf8_unchecked_mut,
19761980
str_len,
19771981
str_split_whitespace,
19781982
str_starts_with,

library/core/src/str/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ impl str {
238238
/// assert_eq!("💖", sparkle_heart);
239239
/// ```
240240
#[unstable(feature = "inherent_str_constructors", issue = "131114")]
241+
#[rustc_diagnostic_item = "str_inherent_from_utf8"]
241242
pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
242243
converts::from_utf8(v)
243244
}
@@ -274,6 +275,7 @@ impl str {
274275
/// errors that can be returned.
275276
#[unstable(feature = "inherent_str_constructors", issue = "131114")]
276277
#[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")]
278+
#[rustc_diagnostic_item = "str_inherent_from_utf8_mut"]
277279
pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
278280
converts::from_utf8_mut(v)
279281
}
@@ -306,6 +308,7 @@ impl str {
306308
#[inline]
307309
#[must_use]
308310
#[unstable(feature = "inherent_str_constructors", issue = "131114")]
311+
#[rustc_diagnostic_item = "str_inherent_from_utf8_unchecked"]
309312
pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
310313
// SAFETY: converts::from_utf8_unchecked has the same safety requirements as this function.
311314
unsafe { converts::from_utf8_unchecked(v) }
@@ -331,6 +334,7 @@ impl str {
331334
#[inline]
332335
#[must_use]
333336
#[unstable(feature = "inherent_str_constructors", issue = "131114")]
337+
#[rustc_diagnostic_item = "str_inherent_from_utf8_unchecked_mut"]
334338
pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
335339
// SAFETY: converts::from_utf8_unchecked_mut has the same safety requirements as this function.
336340
unsafe { converts::from_utf8_unchecked_mut(v) }

tests/ui/lint/invalid_from_utf8.rs

+52-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
//@ check-pass
22

33
#![feature(concat_bytes)]
4-
4+
#![feature(inherent_str_constructors)]
55
#![warn(invalid_from_utf8_unchecked)]
66
#![warn(invalid_from_utf8)]
77

88
pub fn from_utf8_unchecked_mut() {
99
// Valid
1010
unsafe {
1111
std::str::from_utf8_unchecked_mut(&mut [99, 108, 105, 112, 112, 121]);
12+
str::from_utf8_unchecked_mut(&mut [99, 108, 105, 112, 112, 121]);
1213
std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'i', b'p', b'p', b'y']);
14+
str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'i', b'p', b'p', b'y']);
1315

1416
let x = 0xA0;
1517
std::str::from_utf8_unchecked_mut(&mut [0xC0, x]);
@@ -19,101 +21,150 @@ pub fn from_utf8_unchecked_mut() {
1921
unsafe {
2022
std::str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
2123
//~^ WARN calls to `std::str::from_utf8_unchecked_mut`
24+
str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
25+
//~^ WARN calls to `str::from_utf8_unchecked_mut`
2226
std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
2327
//~^ WARN calls to `std::str::from_utf8_unchecked_mut`
28+
str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
29+
//~^ WARN calls to `str::from_utf8_unchecked_mut`
2430
}
2531
}
2632

2733
pub fn from_utf8_unchecked() {
2834
// Valid
2935
unsafe {
3036
std::str::from_utf8_unchecked(&[99, 108, 105, 112, 112, 121]);
37+
str::from_utf8_unchecked(&[99, 108, 105, 112, 112, 121]);
3138
std::str::from_utf8_unchecked(&[b'c', b'l', b'i', b'p', b'p', b'y']);
39+
str::from_utf8_unchecked(&[b'c', b'l', b'i', b'p', b'p', b'y']);
3240
std::str::from_utf8_unchecked(b"clippy");
41+
str::from_utf8_unchecked(b"clippy");
3342

3443
let x = 0xA0;
3544
std::str::from_utf8_unchecked(&[0xC0, x]);
45+
str::from_utf8_unchecked(&[0xC0, x]);
3646
}
3747

3848
// Invalid
3949
unsafe {
4050
std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]);
4151
//~^ WARN calls to `std::str::from_utf8_unchecked`
52+
str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]);
53+
//~^ WARN calls to `str::from_utf8_unchecked`
4254
std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
4355
//~^ WARN calls to `std::str::from_utf8_unchecked`
56+
str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
57+
//~^ WARN calls to `str::from_utf8_unchecked`
4458
std::str::from_utf8_unchecked(b"cl\x82ippy");
4559
//~^ WARN calls to `std::str::from_utf8_unchecked`
60+
str::from_utf8_unchecked(b"cl\x82ippy");
61+
//~^ WARN calls to `str::from_utf8_unchecked`
4662
std::str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy"));
4763
//~^ WARN calls to `std::str::from_utf8_unchecked`
64+
str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy"));
65+
//~^ WARN calls to `str::from_utf8_unchecked`
4866
}
4967
}
5068

5169
pub fn from_utf8_mut() {
5270
// Valid
5371
{
5472
std::str::from_utf8_mut(&mut [99, 108, 105, 112, 112, 121]);
73+
str::from_utf8_mut(&mut [99, 108, 105, 112, 112, 121]);
5574
std::str::from_utf8_mut(&mut [b'c', b'l', b'i', b'p', b'p', b'y']);
75+
str::from_utf8_mut(&mut [b'c', b'l', b'i', b'p', b'p', b'y']);
5676

5777
let x = 0xa0;
5878
std::str::from_utf8_mut(&mut [0xc0, x]);
79+
str::from_utf8_mut(&mut [0xc0, x]);
5980
}
6081

6182
// Invalid
6283
{
6384
std::str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
6485
//~^ WARN calls to `std::str::from_utf8_mut`
86+
str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
87+
//~^ WARN calls to `str::from_utf8_mut`
6588
std::str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
6689
//~^ WARN calls to `std::str::from_utf8_mut`
90+
str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
91+
//~^ WARN calls to `str::from_utf8_mut`
6792
}
6893
}
6994

7095
pub fn from_utf8() {
7196
// Valid
7297
{
7398
std::str::from_utf8(&[99, 108, 105, 112, 112, 121]);
99+
str::from_utf8(&[99, 108, 105, 112, 112, 121]);
74100
std::str::from_utf8(&[b'c', b'l', b'i', b'p', b'p', b'y']);
101+
str::from_utf8(&[b'c', b'l', b'i', b'p', b'p', b'y']);
75102
std::str::from_utf8(b"clippy");
103+
str::from_utf8(b"clippy");
76104

77105
let x = 0xA0;
78106
std::str::from_utf8(&[0xC0, x]);
107+
str::from_utf8(&[0xC0, x]);
79108
}
80109

81110
// Invalid
82111
{
83112
std::str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]);
84113
//~^ WARN calls to `std::str::from_utf8`
114+
str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]);
115+
//~^ WARN calls to `str::from_utf8`
85116
std::str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
86117
//~^ WARN calls to `std::str::from_utf8`
118+
str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
119+
//~^ WARN calls to `str::from_utf8`
87120
std::str::from_utf8(b"cl\x82ippy");
88121
//~^ WARN calls to `std::str::from_utf8`
122+
str::from_utf8(b"cl\x82ippy");
123+
//~^ WARN calls to `str::from_utf8`
89124
std::str::from_utf8(concat_bytes!(b"cl", b"\x82ippy"));
90125
//~^ WARN calls to `std::str::from_utf8`
126+
str::from_utf8(concat_bytes!(b"cl", b"\x82ippy"));
127+
//~^ WARN calls to `str::from_utf8`
91128
}
92129
}
93130

94131
pub fn from_utf8_with_indirections() {
95132
let mut a = [99, 108, 130, 105, 112, 112, 121];
96133
std::str::from_utf8_mut(&mut a);
97134
//~^ WARN calls to `std::str::from_utf8_mut`
135+
str::from_utf8_mut(&mut a);
136+
//~^ WARN calls to `str::from_utf8_mut`
98137
let mut b = &mut a;
99138
let mut c = b;
100139
std::str::from_utf8_mut(c);
101140
//~^ WARN calls to `std::str::from_utf8_mut`
141+
str::from_utf8_mut(c);
142+
//~^ WARN calls to `str::from_utf8_mut`
102143
let mut c = &[99, 108, 130, 105, 112, 112, 121];
103144
std::str::from_utf8(c);
104145
//~^ WARN calls to `std::str::from_utf8`
146+
str::from_utf8(c);
147+
//~^ WARN calls to `str::from_utf8`
105148
const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121];
106149
std::str::from_utf8(&INVALID_1);
107150
//~^ WARN calls to `std::str::from_utf8`
151+
str::from_utf8(&INVALID_1);
152+
//~^ WARN calls to `str::from_utf8`
108153
static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121];
109154
std::str::from_utf8(&INVALID_2);
110155
//~^ WARN calls to `std::str::from_utf8`
156+
str::from_utf8(&INVALID_2);
157+
//~^ WARN calls to `str::from_utf8`
111158
const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121];
112159
std::str::from_utf8(INVALID_3);
113160
//~^ WARN calls to `std::str::from_utf8`
161+
str::from_utf8(INVALID_3);
162+
//~^ WARN calls to `str::from_utf8`
114163
const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] };
115164
std::str::from_utf8(INVALID_4);
116165
//~^ WARN calls to `std::str::from_utf8`
166+
str::from_utf8(INVALID_4);
167+
//~^ WARN calls to `str::from_utf8`
117168
}
118169

119170
fn main() {}

0 commit comments

Comments
 (0)