11use if_chain:: if_chain;
22use rustc_errors:: Applicability ;
3- use rustc_hir:: * ;
3+ use rustc_hir:: { def , Expr , ExprKind , PrimTy , QPath , TyKind } ;
44use rustc_lint:: { LateContext , LateLintPass } ;
5+ use rustc_middle:: ty:: Ty ;
56use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
7+ use rustc_span:: symbol:: sym;
68
9+ use crate :: utils:: is_type_diagnostic_item;
710use crate :: utils:: span_lint_and_sugg;
811use 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+ }
0 commit comments