1
1
use crate :: rustc:: hir:: * ;
2
- use crate :: rustc:: lint:: { LateContext , LateLintPass , LintArray , LintPass } ;
2
+ use crate :: rustc:: lint:: { LateContext , LateLintPass , LintArray , LintContext , LintPass } ;
3
3
use crate :: rustc:: { declare_tool_lint, lint_array} ;
4
4
use crate :: syntax:: source_map:: Spanned ;
5
5
use crate :: utils:: SpanlessEq ;
@@ -82,7 +82,14 @@ impl LintPass for StringAdd {
82
82
83
83
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for StringAdd {
84
84
fn check_expr ( & mut self , cx : & LateContext < ' a , ' tcx > , e : & ' tcx Expr ) {
85
- if let ExprKind :: Binary ( Spanned { node : BinOpKind :: Add , .. } , ref left, _) = e. node {
85
+ if let ExprKind :: Binary (
86
+ Spanned {
87
+ node : BinOpKind :: Add , ..
88
+ } ,
89
+ ref left,
90
+ _,
91
+ ) = e. node
92
+ {
86
93
if is_string ( cx, left) {
87
94
if !is_allowed ( cx, STRING_ADD_ASSIGN , e. id ) {
88
95
let parent = get_parent_expr ( cx, e) ;
@@ -122,13 +129,15 @@ fn is_string(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
122
129
123
130
fn is_add ( cx : & LateContext < ' _ , ' _ > , src : & Expr , target : & Expr ) -> bool {
124
131
match src. node {
125
- ExprKind :: Binary ( Spanned { node : BinOpKind :: Add , .. } , ref left, _) => SpanlessEq :: new ( cx) . eq_expr ( target, left) ,
132
+ ExprKind :: Binary (
133
+ Spanned {
134
+ node : BinOpKind :: Add , ..
135
+ } ,
136
+ ref left,
137
+ _,
138
+ ) => SpanlessEq :: new ( cx) . eq_expr ( target, left) ,
126
139
ExprKind :: Block ( ref block, _) => {
127
- block. stmts . is_empty ( )
128
- && block
129
- . expr
130
- . as_ref ( )
131
- . map_or ( false , |expr| is_add ( cx, expr, target) )
140
+ block. stmts . is_empty ( ) && block. expr . as_ref ( ) . map_or ( false , |expr| is_add ( cx, expr, target) )
132
141
} ,
133
142
_ => false ,
134
143
}
@@ -152,7 +161,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
152
161
if path. ident . name == "as_bytes" {
153
162
if let ExprKind :: Lit ( ref lit) = args[ 0 ] . node {
154
163
if let LitKind :: Str ( ref lit_content, _) = lit. node {
155
- if lit_content. as_str ( ) . chars ( ) . all ( |c| c. is_ascii ( ) ) && !in_macro ( args[ 0 ] . span ) {
164
+ let callsite = snippet ( cx, args[ 0 ] . span . source_callsite ( ) , "" ) ;
165
+ let expanded = format ! ( "\" {}\" " , lit_content. as_str( ) ) ;
166
+ if callsite. starts_with ( "include_str!" ) {
167
+ span_lint_and_sugg (
168
+ cx,
169
+ STRING_LIT_AS_BYTES ,
170
+ e. span ,
171
+ "calling `as_bytes()` on `include_str!(..)`" ,
172
+ "consider using `include_bytes!(..)` instead" ,
173
+ snippet ( cx, args[ 0 ] . span , r#""foo""# ) . replacen ( "include_str" , "include_bytes" , 1 ) ,
174
+ ) ;
175
+ } else if callsite == expanded
176
+ && lit_content. as_str ( ) . chars ( ) . all ( |c| c. is_ascii ( ) )
177
+ && !in_macro ( args[ 0 ] . span )
178
+ {
156
179
span_lint_and_sugg (
157
180
cx,
158
181
STRING_LIT_AS_BYTES ,
0 commit comments