Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit bf55aee

Browse files
Updated from_str_radix_10 sugg to be slightly smarter and ran bless
1 parent d36fe85 commit bf55aee

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

clippy_lints/src/from_str_radix_10.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
use if_chain::if_chain;
22
use rustc_errors::Applicability;
3-
use rustc_hir::*;
3+
use rustc_hir::{def, Expr, ExprKind, PrimTy, QPath, TyKind};
44
use rustc_lint::{LateContext, LateLintPass};
5+
use rustc_middle::ty::Ty;
56
use rustc_session::{declare_lint_pass, declare_tool_lint};
7+
use rustc_span::symbol::sym;
68

9+
use crate::utils::is_type_diagnostic_item;
710
use crate::utils::span_lint_and_sugg;
811
use crate::utils::sugg::Sugg;
912

@@ -40,8 +43,7 @@ impl LateLintPass<'tcx> for FromStrRadix10 {
4043
fn check_expr(&mut self, cx: &LateContext<'tcx>, exp: &Expr<'tcx>) {
4144
if_chain! {
4245
if let ExprKind::Call(maybe_path, arguments) = &exp.kind;
43-
if let ExprKind::Path(qpath) = &maybe_path.kind;
44-
if let QPath::TypeRelative(ty, pathseg) = &qpath;
46+
if let ExprKind::Path(QPath::TypeRelative(ty, pathseg)) = &maybe_path.kind;
4547

4648
// check if the first part of the path is some integer primitive
4749
if let TyKind::Path(ty_qpath) = &ty.kind;
@@ -59,9 +61,20 @@ impl LateLintPass<'tcx> for FromStrRadix10 {
5961
if let rustc_ast::ast::LitKind::Int(10, _) = lit.node;
6062

6163
then {
64+
let expr = if let ExprKind::AddrOf(_, _, expr) = &arguments[0].kind {
65+
let ty = cx.typeck_results().expr_ty(expr);
66+
if is_ty_stringish(cx, ty) {
67+
expr
68+
} else {
69+
&arguments[0]
70+
}
71+
} else {
72+
&arguments[0]
73+
};
74+
6275
let sugg = Sugg::hir_with_applicability(
6376
cx,
64-
&arguments[0],
77+
expr,
6578
"<string>",
6679
&mut Applicability::MachineApplicable
6780
).maybe_par();
@@ -79,3 +92,8 @@ impl LateLintPass<'tcx> for FromStrRadix10 {
7992
}
8093
}
8194
}
95+
96+
/// Checks if a Ty is `String` or `&str`
97+
fn is_ty_stringish(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
98+
is_type_diagnostic_item(cx, ty, sym::string_type) || is_type_diagnostic_item(cx, ty, sym::str)
99+
}

tests/ui/from_str_radix_10.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
3535
let string = "300";
3636
i32::from_str_radix(string, 10)?;
3737

38+
let stringier = "400".to_string();
39+
i32::from_str_radix(&stringier, 10)?;
40+
3841
// none of these should trigger the lint
3942
u16::from_str_radix("20", 3)?;
4043
i32::from_str_radix("45", 12)?;

tests/ui/from_str_radix_10.stderr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ error: this call to `from_str_radix` can be replaced with a call to `str::parse`
2828
--> $DIR/from_str_radix_10.rs:32:5
2929
|
3030
LL | u16::from_str_radix(&("10".to_owned() + "5"), 10)?;
31-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&("10".to_owned() + "5")).parse::<u16>()`
31+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(("10".to_owned() + "5")).parse::<u16>()`
3232

3333
error: this call to `from_str_radix` can be replaced with a call to `str::parse`
3434
--> $DIR/from_str_radix_10.rs:33:5
@@ -42,5 +42,11 @@ error: this call to `from_str_radix` can be replaced with a call to `str::parse`
4242
LL | i32::from_str_radix(string, 10)?;
4343
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.parse::<i32>()`
4444

45-
error: aborting due to 7 previous errors
45+
error: this call to `from_str_radix` can be replaced with a call to `str::parse`
46+
--> $DIR/from_str_radix_10.rs:39:5
47+
|
48+
LL | i32::from_str_radix(&stringier, 10)?;
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `stringier.parse::<i32>()`
50+
51+
error: aborting due to 8 previous errors
4652

0 commit comments

Comments
 (0)