Skip to content

Commit d6accfc

Browse files
committed
Auto merge of #4808 - euclio:string-lit-as-bytes, r=phansch
trigger string_lit_as_bytes when literal has escapes --- changelog: fix string_lit_as_bytes false negative Depends on rust-lang/rust#66349. Fixes #4796.
2 parents 7f745da + d33ad45 commit d6accfc

File tree

4 files changed

+52
-47
lines changed

4 files changed

+52
-47
lines changed

clippy_lints/src/strings.rs

+41-46
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use rustc::{declare_lint_pass, declare_tool_lint};
44
use rustc_errors::Applicability;
55
use syntax::source_map::Spanned;
66

7+
use if_chain::if_chain;
8+
79
use crate::utils::SpanlessEq;
810
use crate::utils::{get_parent_expr, is_allowed, match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty};
911

@@ -146,53 +148,46 @@ declare_lint_pass!(StringLitAsBytes => [STRING_LIT_AS_BYTES]);
146148
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
147149
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
148150
use crate::utils::{snippet, snippet_with_applicability};
149-
use syntax::ast::{LitKind, StrStyle};
151+
use syntax::ast::LitKind;
150152

151-
if let ExprKind::MethodCall(ref path, _, ref args) = e.kind {
152-
if path.ident.name == sym!(as_bytes) {
153-
if let ExprKind::Lit(ref lit) = args[0].kind {
154-
if let LitKind::Str(ref lit_content, style) = lit.node {
155-
let callsite = snippet(cx, args[0].span.source_callsite(), r#""foo""#);
156-
let expanded = if let StrStyle::Raw(n) = style {
157-
let term = "#".repeat(usize::from(n));
158-
format!("r{0}\"{1}\"{0}", term, lit_content.as_str())
159-
} else {
160-
format!("\"{}\"", lit_content.as_str())
161-
};
162-
let mut applicability = Applicability::MachineApplicable;
163-
if callsite.starts_with("include_str!") {
164-
span_lint_and_sugg(
165-
cx,
166-
STRING_LIT_AS_BYTES,
167-
e.span,
168-
"calling `as_bytes()` on `include_str!(..)`",
169-
"consider using `include_bytes!(..)` instead",
170-
snippet_with_applicability(cx, args[0].span, r#""foo""#, &mut applicability).replacen(
171-
"include_str",
172-
"include_bytes",
173-
1,
174-
),
175-
applicability,
176-
);
177-
} else if callsite == expanded
178-
&& lit_content.as_str().chars().all(|c| c.is_ascii())
179-
&& lit_content.as_str().len() <= MAX_LENGTH_BYTE_STRING_LIT
180-
&& !args[0].span.from_expansion()
181-
{
182-
span_lint_and_sugg(
183-
cx,
184-
STRING_LIT_AS_BYTES,
185-
e.span,
186-
"calling `as_bytes()` on a string literal",
187-
"consider using a byte string literal instead",
188-
format!(
189-
"b{}",
190-
snippet_with_applicability(cx, args[0].span, r#""foo""#, &mut applicability)
191-
),
192-
applicability,
193-
);
194-
}
195-
}
153+
if_chain! {
154+
if let ExprKind::MethodCall(path, _, args) = &e.kind;
155+
if path.ident.name == sym!(as_bytes);
156+
if let ExprKind::Lit(lit) = &args[0].kind;
157+
if let LitKind::Str(lit_content, _) = &lit.node;
158+
then {
159+
let callsite = snippet(cx, args[0].span.source_callsite(), r#""foo""#);
160+
let mut applicability = Applicability::MachineApplicable;
161+
if callsite.starts_with("include_str!") {
162+
span_lint_and_sugg(
163+
cx,
164+
STRING_LIT_AS_BYTES,
165+
e.span,
166+
"calling `as_bytes()` on `include_str!(..)`",
167+
"consider using `include_bytes!(..)` instead",
168+
snippet_with_applicability(cx, args[0].span, r#""foo""#, &mut applicability).replacen(
169+
"include_str",
170+
"include_bytes",
171+
1,
172+
),
173+
applicability,
174+
);
175+
} else if lit_content.as_str().is_ascii()
176+
&& lit_content.as_str().len() <= MAX_LENGTH_BYTE_STRING_LIT
177+
&& !args[0].span.from_expansion()
178+
{
179+
span_lint_and_sugg(
180+
cx,
181+
STRING_LIT_AS_BYTES,
182+
e.span,
183+
"calling `as_bytes()` on a string literal",
184+
"consider using a byte string literal instead",
185+
format!(
186+
"b{}",
187+
snippet_with_applicability(cx, args[0].span, r#""foo""#, &mut applicability)
188+
),
189+
applicability,
190+
);
196191
}
197192
}
198193
}

tests/ui/string_lit_as_bytes.fixed

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ fn str_lit_as_bytes() {
1515
let strify = stringify!(foobar).as_bytes();
1616

1717
let includestr = include_bytes!("entry_unfixable.rs");
18+
19+
let _ = b"string with newline\t\n";
1820
}
1921

2022
fn main() {}

tests/ui/string_lit_as_bytes.rs

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ fn str_lit_as_bytes() {
1515
let strify = stringify!(foobar).as_bytes();
1616

1717
let includestr = include_str!("entry_unfixable.rs").as_bytes();
18+
19+
let _ = "string with newline\t\n".as_bytes();
1820
}
1921

2022
fn main() {}

tests/ui/string_lit_as_bytes.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,11 @@ error: calling `as_bytes()` on `include_str!(..)`
1818
LL | let includestr = include_str!("entry_unfixable.rs").as_bytes();
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("entry_unfixable.rs")`
2020

21-
error: aborting due to 3 previous errors
21+
error: calling `as_bytes()` on a string literal
22+
--> $DIR/string_lit_as_bytes.rs:19:13
23+
|
24+
LL | let _ = "string with newline/t/n".as_bytes();
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"string with newline/t/n"`
26+
27+
error: aborting due to 4 previous errors
2228

0 commit comments

Comments
 (0)