@@ -1721,14 +1721,49 @@ fn lint_expect_fun_call(
17211721 if match_type ( cx, arg_ty, & paths:: STRING ) {
17221722 return false ;
17231723 }
1724- if let ty:: Ref ( ty :: ReStatic , ty, ..) = arg_ty. kind {
1725- if ty. kind == ty:: Str {
1724+ if let ty:: Ref ( _ , ty, ..) = arg_ty. kind {
1725+ if ty. kind == ty:: Str && can_be_static_str ( cx , arg ) {
17261726 return false ;
17271727 }
17281728 } ;
17291729 true
17301730 }
17311731
1732+ // Check if an expression could have type `&'static str`, knowing that it
1733+ // has type `&str` for some lifetime.
1734+ fn can_be_static_str ( cx : & LateContext < ' _ , ' _ > , arg : & hir:: Expr < ' _ > ) -> bool {
1735+ match arg. kind {
1736+ hir:: ExprKind :: Lit ( _) => true ,
1737+ hir:: ExprKind :: Call ( fun, _) => {
1738+ if let hir:: ExprKind :: Path ( ref p) = fun. kind {
1739+ match cx. tables . qpath_res ( p, fun. hir_id ) {
1740+ hir:: def:: Res :: Def ( hir:: def:: DefKind :: Fn , def_id)
1741+ | hir:: def:: Res :: Def ( hir:: def:: DefKind :: Method , def_id) => matches ! (
1742+ cx. tcx. fn_sig( def_id) . output( ) . skip_binder( ) . kind,
1743+ ty:: Ref ( ty:: ReStatic , ..)
1744+ ) ,
1745+ _ => false ,
1746+ }
1747+ } else {
1748+ false
1749+ }
1750+ } ,
1751+ hir:: ExprKind :: MethodCall ( ..) => cx. tables . type_dependent_def_id ( arg. hir_id ) . map_or ( false , |method_id| {
1752+ matches ! (
1753+ cx. tcx. fn_sig( method_id) . output( ) . skip_binder( ) . kind,
1754+ ty:: Ref ( ty:: ReStatic , ..)
1755+ )
1756+ } ) ,
1757+ hir:: ExprKind :: Path ( ref p) => match cx. tables . qpath_res ( p, arg. hir_id ) {
1758+ hir:: def:: Res :: Def ( hir:: def:: DefKind :: Const , _) | hir:: def:: Res :: Def ( hir:: def:: DefKind :: Static , _) => {
1759+ true
1760+ } ,
1761+ _ => false ,
1762+ } ,
1763+ _ => false ,
1764+ }
1765+ }
1766+
17321767 fn generate_format_arg_snippet (
17331768 cx : & LateContext < ' _ , ' _ > ,
17341769 a : & hir:: Expr < ' _ > ,
0 commit comments