mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-24 05:33:27 +00:00
3217: Fix string_lit_as_bytes lint for macros r=phansch a=yaahallo Prior to this change, string_lit_as_bytes would trigger for constructs like `include_str!("filename").as_bytes()` and would recommend fixing it by rewriting as `binclude_str!("filename")`. This change updates the lint to act as an EarlyLintPass lint. It then differentiates between string literals and macros that have bytes yielding alternatives. Closes #3205 3366: Don't expand macros in some suggestions r=oli-obk a=phansch Fixes #1148 Fixes #1628 Fixes #2455 Fixes #3023 Fixes #3333 Fixes #3360 Co-authored-by: Jane Lusby <jlusby42@gmail.com> Co-authored-by: Philipp Hansch <dev@phansch.net>
This commit is contained in:
commit
14d2700b6f
13 changed files with 123 additions and 52 deletions
|
@ -12,7 +12,7 @@ use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use crate::rustc::{declare_tool_lint, lint_array};
|
use crate::rustc::{declare_tool_lint, lint_array};
|
||||||
use crate::rustc::hir::*;
|
use crate::rustc::hir::*;
|
||||||
use crate::syntax::ast::NodeId;
|
use crate::syntax::ast::NodeId;
|
||||||
use crate::utils::{in_macro, match_def_path, match_trait_method, same_tys, snippet, span_lint_and_then};
|
use crate::utils::{in_macro, match_def_path, match_trait_method, same_tys, snippet, snippet_with_macro_callsite, span_lint_and_then};
|
||||||
use crate::utils::{opt_def_id, paths, resolve_node};
|
use crate::utils::{opt_def_id, paths, resolve_node};
|
||||||
use crate::rustc_errors::Applicability;
|
use crate::rustc_errors::Applicability;
|
||||||
|
|
||||||
|
@ -72,7 +72,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityConversion {
|
||||||
let a = cx.tables.expr_ty(e);
|
let a = cx.tables.expr_ty(e);
|
||||||
let b = cx.tables.expr_ty(&args[0]);
|
let b = cx.tables.expr_ty(&args[0]);
|
||||||
if same_tys(cx, a, b) {
|
if same_tys(cx, a, b) {
|
||||||
let sugg = snippet(cx, args[0].span, "<expr>").into_owned();
|
let sugg = snippet_with_macro_callsite(cx, args[0].span, "<expr>").to_string();
|
||||||
|
|
||||||
span_lint_and_then(cx, IDENTITY_CONVERSION, e.span, "identical conversion", |db| {
|
span_lint_and_then(cx, IDENTITY_CONVERSION, e.span, "identical conversion", |db| {
|
||||||
db.span_suggestion_with_applicability(
|
db.span_suggestion_with_applicability(
|
||||||
e.span,
|
e.span,
|
||||||
|
|
|
@ -19,7 +19,8 @@ use crate::syntax::ast::LitKind;
|
||||||
use crate::syntax::source_map::Span;
|
use crate::syntax::source_map::Span;
|
||||||
use crate::utils::paths;
|
use crate::utils::paths;
|
||||||
use crate::utils::{expr_block, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg,
|
use crate::utils::{expr_block, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg,
|
||||||
remove_blocks, snippet, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty};
|
remove_blocks, snippet, span_lint_and_sugg, span_lint_and_then,
|
||||||
|
span_note_and_lint, walk_ptrs_ty};
|
||||||
use crate::utils::sugg::Sugg;
|
use crate::utils::sugg::Sugg;
|
||||||
use crate::consts::{constant, Constant};
|
use crate::consts::{constant, Constant};
|
||||||
use crate::rustc_errors::Applicability;
|
use crate::rustc_errors::Applicability;
|
||||||
|
|
|
@ -21,7 +21,7 @@ use crate::utils::sugg;
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
get_arg_name, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, is_self, is_self_ty,
|
get_arg_name, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, is_self, is_self_ty,
|
||||||
iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method, match_type,
|
iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method, match_type,
|
||||||
match_var, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, snippet, span_lint,
|
match_var, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, snippet, snippet_with_macro_callsite, span_lint,
|
||||||
span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq,
|
span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq,
|
||||||
};
|
};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
|
@ -1062,9 +1062,9 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa
|
||||||
}
|
}
|
||||||
|
|
||||||
let sugg: Cow<'_, _> = match (fn_has_arguments, !or_has_args) {
|
let sugg: Cow<'_, _> = match (fn_has_arguments, !or_has_args) {
|
||||||
(true, _) => format!("|_| {}", snippet(cx, arg.span, "..")).into(),
|
(true, _) => format!("|_| {}", snippet_with_macro_callsite(cx, arg.span, "..")).into(),
|
||||||
(false, false) => format!("|| {}", snippet(cx, arg.span, "..")).into(),
|
(false, false) => format!("|| {}", snippet_with_macro_callsite(cx, arg.span, "..")).into(),
|
||||||
(false, true) => snippet(cx, fun_span, ".."),
|
(false, true) => snippet_with_macro_callsite(cx, fun_span, ".."),
|
||||||
};
|
};
|
||||||
let span_replace_word = method_span.with_hi(span.hi());
|
let span_replace_word = method_span.with_hi(span.hi());
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
|
||||||
use crate::rustc::hir::*;
|
use crate::rustc::hir::*;
|
||||||
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use crate::rustc::{declare_tool_lint, lint_array};
|
use crate::rustc::{declare_tool_lint, lint_array};
|
||||||
|
@ -92,7 +91,14 @@ impl LintPass for StringAdd {
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||||
if let ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) = e.node {
|
if let ExprKind::Binary(
|
||||||
|
Spanned {
|
||||||
|
node: BinOpKind::Add, ..
|
||||||
|
},
|
||||||
|
ref left,
|
||||||
|
_,
|
||||||
|
) = e.node
|
||||||
|
{
|
||||||
if is_string(cx, left) {
|
if is_string(cx, left) {
|
||||||
if !is_allowed(cx, STRING_ADD_ASSIGN, e.id) {
|
if !is_allowed(cx, STRING_ADD_ASSIGN, e.id) {
|
||||||
let parent = get_parent_expr(cx, e);
|
let parent = get_parent_expr(cx, e);
|
||||||
|
@ -132,13 +138,15 @@ fn is_string(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
|
||||||
|
|
||||||
fn is_add(cx: &LateContext<'_, '_>, src: &Expr, target: &Expr) -> bool {
|
fn is_add(cx: &LateContext<'_, '_>, src: &Expr, target: &Expr) -> bool {
|
||||||
match src.node {
|
match src.node {
|
||||||
ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) => SpanlessEq::new(cx).eq_expr(target, left),
|
ExprKind::Binary(
|
||||||
|
Spanned {
|
||||||
|
node: BinOpKind::Add, ..
|
||||||
|
},
|
||||||
|
ref left,
|
||||||
|
_,
|
||||||
|
) => SpanlessEq::new(cx).eq_expr(target, left),
|
||||||
ExprKind::Block(ref block, _) => {
|
ExprKind::Block(ref block, _) => {
|
||||||
block.stmts.is_empty()
|
block.stmts.is_empty() && block.expr.as_ref().map_or(false, |expr| is_add(cx, expr, target))
|
||||||
&& block
|
|
||||||
.expr
|
|
||||||
.as_ref()
|
|
||||||
.map_or(false, |expr| is_add(cx, expr, target))
|
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -155,14 +163,33 @@ impl LintPass for StringLitAsBytes {
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||||
use crate::syntax::ast::LitKind;
|
use crate::syntax::ast::{LitKind, StrStyle};
|
||||||
use crate::utils::{in_macro, snippet};
|
use crate::utils::{in_macro, snippet};
|
||||||
|
|
||||||
if let ExprKind::MethodCall(ref path, _, ref args) = e.node {
|
if let ExprKind::MethodCall(ref path, _, ref args) = e.node {
|
||||||
if path.ident.name == "as_bytes" {
|
if path.ident.name == "as_bytes" {
|
||||||
if let ExprKind::Lit(ref lit) = args[0].node {
|
if let ExprKind::Lit(ref lit) = args[0].node {
|
||||||
if let LitKind::Str(ref lit_content, _) = lit.node {
|
if let LitKind::Str(ref lit_content, style) = lit.node {
|
||||||
if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(args[0].span) {
|
let callsite = snippet(cx, args[0].span.source_callsite(), r#""foo""#);
|
||||||
|
let expanded = if let StrStyle::Raw(n) = style {
|
||||||
|
let term = (0..n).map(|_| '#').collect::<String>();
|
||||||
|
format!("r{0}\"{1}\"{0}", term, lit_content.as_str())
|
||||||
|
} else {
|
||||||
|
format!("\"{}\"", lit_content.as_str())
|
||||||
|
};
|
||||||
|
if callsite.starts_with("include_str!") {
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
STRING_LIT_AS_BYTES,
|
||||||
|
e.span,
|
||||||
|
"calling `as_bytes()` on `include_str!(..)`",
|
||||||
|
"consider using `include_bytes!(..)` instead",
|
||||||
|
snippet(cx, args[0].span, r#""foo""#).replacen("include_str", "include_bytes", 1),
|
||||||
|
);
|
||||||
|
} else if callsite == expanded
|
||||||
|
&& lit_content.as_str().chars().all(|c| c.is_ascii())
|
||||||
|
&& !in_macro(args[0].span)
|
||||||
|
{
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
cx,
|
cx,
|
||||||
STRING_LIT_AS_BYTES,
|
STRING_LIT_AS_BYTES,
|
||||||
|
|
|
@ -362,6 +362,12 @@ pub fn snippet<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str)
|
||||||
snippet_opt(cx, span).map_or_else(|| Cow::Borrowed(default), From::from)
|
snippet_opt(cx, span).map_or_else(|| Cow::Borrowed(default), From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Same as `snippet`, but should only be used when it's clear that the input span is
|
||||||
|
/// not a macro argument.
|
||||||
|
pub fn snippet_with_macro_callsite<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> {
|
||||||
|
snippet(cx, span.source_callsite(), default)
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert a span to a code snippet. Returns `None` if not available.
|
/// Convert a span to a code snippet. Returns `None` if not available.
|
||||||
pub fn snippet_opt<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Option<String> {
|
pub fn snippet_opt<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Option<String> {
|
||||||
cx.sess().source_map().span_to_snippet(span).ok()
|
cx.sess().source_map().span_to_snippet(span).ok()
|
||||||
|
@ -400,7 +406,10 @@ pub fn expr_block<'a, 'b, T: LintContext<'b>>(
|
||||||
) -> Cow<'a, str> {
|
) -> Cow<'a, str> {
|
||||||
let code = snippet_block(cx, expr.span, default);
|
let code = snippet_block(cx, expr.span, default);
|
||||||
let string = option.unwrap_or_default();
|
let string = option.unwrap_or_default();
|
||||||
if let ExprKind::Block(_, _) = expr.node {
|
if in_macro(expr.span) {
|
||||||
|
Cow::Owned(format!("{{ {} }}", snippet_with_macro_callsite(cx, expr.span, default)))
|
||||||
|
}
|
||||||
|
else if let ExprKind::Block(_, _) = expr.node {
|
||||||
Cow::Owned(format!("{}{}", code, string))
|
Cow::Owned(format!("{}{}", code, string))
|
||||||
} else if string.is_empty() {
|
} else if string.is_empty() {
|
||||||
Cow::Owned(format!("{{ {} }}", code))
|
Cow::Owned(format!("{{ {} }}", code))
|
||||||
|
|
|
@ -53,4 +53,5 @@ fn main() {
|
||||||
let _ = String::from(format!("A: {:04}", 123));
|
let _ = String::from(format!("A: {:04}", 123));
|
||||||
let _ = "".lines().into_iter();
|
let _ = "".lines().into_iter();
|
||||||
let _ = vec![1, 2, 3].into_iter().into_iter();
|
let _ = vec![1, 2, 3].into_iter().into_iter();
|
||||||
|
let _: String = format!("Hello {}", "world").into();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,5 +58,11 @@ error: identical conversion
|
||||||
55 | let _ = vec![1, 2, 3].into_iter().into_iter();
|
55 | let _ = vec![1, 2, 3].into_iter().into_iter();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()`
|
||||||
|
|
||||||
error: aborting due to 9 previous errors
|
error: identical conversion
|
||||||
|
--> $DIR/identity_conversion.rs:56:21
|
||||||
|
|
|
||||||
|
56 | let _: String = format!("Hello {}", "world").into();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")`
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ error: you seem to be trying to use match for destructuring a single pattern. Co
|
||||||
51 | | &(v, 1) => println!("{}", v),
|
51 | | &(v, 1) => println!("{}", v),
|
||||||
52 | | _ => println!("none"),
|
52 | | _ => println!("none"),
|
||||||
53 | | }
|
53 | | }
|
||||||
| |_____^ help: try this: `if let &(v, 1) = tup { $ crate :: io :: _print ( format_args_nl ! ( $ ( $ arg ) * ) ) ; } else { $ crate :: io :: _print ( format_args_nl ! ( $ ( $ arg ) * ) ) ; }`
|
| |_____^ help: try this: `if let &(v, 1) = tup { println!("{}", v) } else { println!("none") }`
|
||||||
|
|
||||||
error: you don't need to add `&` to all patterns
|
error: you don't need to add `&` to all patterns
|
||||||
--> $DIR/matches.rs:50:5
|
--> $DIR/matches.rs:50:5
|
||||||
|
|
|
@ -297,7 +297,7 @@ error: use of `unwrap_or` followed by a function call
|
||||||
--> $DIR/methods.rs:339:14
|
--> $DIR/methods.rs:339:14
|
||||||
|
|
|
|
||||||
339 | with_vec.unwrap_or(vec![]);
|
339 | with_vec.unwrap_or(vec![]);
|
||||||
| ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| < [ _ ] > :: into_vec ( box [ $ ( $ x ) , * ] ))`
|
| ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| vec![])`
|
||||||
|
|
||||||
error: use of `unwrap_or` followed by a function call
|
error: use of `unwrap_or` followed by a function call
|
||||||
--> $DIR/methods.rs:344:21
|
--> $DIR/methods.rs:344:21
|
||||||
|
|
|
@ -23,6 +23,15 @@ fn single_match(){
|
||||||
_ => ()
|
_ => ()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let x = Some(1u8);
|
||||||
|
match x {
|
||||||
|
// Note the missing block braces.
|
||||||
|
// We suggest `if let Some(y) = x { .. }` because the macro
|
||||||
|
// is expanded before we can do anything.
|
||||||
|
Some(y) => println!("{:?}", y),
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
|
||||||
let z = (1u8,1u8);
|
let z = (1u8,1u8);
|
||||||
match z {
|
match z {
|
||||||
(2...3, 7...9) => dummy(),
|
(2...3, 7...9) => dummy(),
|
||||||
|
|
|
@ -12,38 +12,50 @@ error: you seem to be trying to use match for destructuring a single pattern. Co
|
||||||
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
||||||
--> $DIR/single_match.rs:27:5
|
--> $DIR/single_match.rs:27:5
|
||||||
|
|
|
|
||||||
27 | / match z {
|
27 | / match x {
|
||||||
28 | | (2...3, 7...9) => dummy(),
|
28 | | // Note the missing block braces.
|
||||||
29 | | _ => {}
|
29 | | // We suggest `if let Some(y) = x { .. }` because the macro
|
||||||
30 | | };
|
30 | | // is expanded before we can do anything.
|
||||||
|
31 | | Some(y) => println!("{:?}", y),
|
||||||
|
32 | | _ => ()
|
||||||
|
33 | | }
|
||||||
|
| |_____^ help: try this: `if let Some(y) = x { println!("{:?}", y) }`
|
||||||
|
|
||||||
|
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
||||||
|
--> $DIR/single_match.rs:36:5
|
||||||
|
|
|
||||||
|
36 | / match z {
|
||||||
|
37 | | (2...3, 7...9) => dummy(),
|
||||||
|
38 | | _ => {}
|
||||||
|
39 | | };
|
||||||
| |_____^ help: try this: `if let (2...3, 7...9) = z { dummy() }`
|
| |_____^ help: try this: `if let (2...3, 7...9) = z { dummy() }`
|
||||||
|
|
||||||
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
||||||
--> $DIR/single_match.rs:53:5
|
--> $DIR/single_match.rs:62:5
|
||||||
|
|
|
|
||||||
53 | / match x {
|
62 | / match x {
|
||||||
54 | | Some(y) => dummy(),
|
63 | | Some(y) => dummy(),
|
||||||
55 | | None => ()
|
64 | | None => ()
|
||||||
56 | | };
|
65 | | };
|
||||||
| |_____^ help: try this: `if let Some(y) = x { dummy() }`
|
| |_____^ help: try this: `if let Some(y) = x { dummy() }`
|
||||||
|
|
||||||
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
||||||
--> $DIR/single_match.rs:58:5
|
--> $DIR/single_match.rs:67:5
|
||||||
|
|
|
|
||||||
58 | / match y {
|
67 | / match y {
|
||||||
59 | | Ok(y) => dummy(),
|
68 | | Ok(y) => dummy(),
|
||||||
60 | | Err(..) => ()
|
69 | | Err(..) => ()
|
||||||
61 | | };
|
70 | | };
|
||||||
| |_____^ help: try this: `if let Ok(y) = y { dummy() }`
|
| |_____^ help: try this: `if let Ok(y) = y { dummy() }`
|
||||||
|
|
||||||
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
||||||
--> $DIR/single_match.rs:65:5
|
--> $DIR/single_match.rs:74:5
|
||||||
|
|
|
|
||||||
65 | / match c {
|
74 | / match c {
|
||||||
66 | | Cow::Borrowed(..) => dummy(),
|
75 | | Cow::Borrowed(..) => dummy(),
|
||||||
67 | | Cow::Owned(..) => (),
|
76 | | Cow::Owned(..) => (),
|
||||||
68 | | };
|
77 | | };
|
||||||
| |_____^ help: try this: `if let Cow::Borrowed(..) = c { dummy() }`
|
| |_____^ help: try this: `if let Cow::Borrowed(..) = c { dummy() }`
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[warn(clippy::string_add)]
|
#[warn(clippy::string_add)]
|
||||||
#[allow(clippy::string_add_assign)]
|
#[allow(clippy::string_add_assign)]
|
||||||
fn add_only() { // ignores assignment distinction
|
fn add_only() {
|
||||||
|
// ignores assignment distinction
|
||||||
let mut x = "".to_owned();
|
let mut x = "".to_owned();
|
||||||
|
|
||||||
for _ in 1..3 {
|
for _ in 1..3 {
|
||||||
|
@ -59,12 +59,17 @@ fn both() {
|
||||||
fn str_lit_as_bytes() {
|
fn str_lit_as_bytes() {
|
||||||
let bs = "hello there".as_bytes();
|
let bs = "hello there".as_bytes();
|
||||||
|
|
||||||
|
let bs = r###"raw string with three ### in it and some " ""###.as_bytes();
|
||||||
|
|
||||||
// no warning, because this cannot be written as a byte string literal:
|
// no warning, because this cannot be written as a byte string literal:
|
||||||
let ubs = "☃".as_bytes();
|
let ubs = "☃".as_bytes();
|
||||||
|
|
||||||
let strify = stringify!(foobar).as_bytes();
|
let strify = stringify!(foobar).as_bytes();
|
||||||
|
|
||||||
|
let includestr = include_str!("entry.rs").as_bytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::assign_op_pattern)]
|
||||||
fn main() {
|
fn main() {
|
||||||
add_only();
|
add_only();
|
||||||
add_assign_only();
|
add_assign_only();
|
||||||
|
@ -72,6 +77,6 @@ fn main() {
|
||||||
|
|
||||||
// the add is only caught for `String`
|
// the add is only caught for `String`
|
||||||
let mut x = 1;
|
let mut x = 1;
|
||||||
; x = x + 1;
|
x = x + 1;
|
||||||
assert_eq!(2, x);
|
assert_eq!(2, x);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,16 +61,16 @@ error: calling `as_bytes()` on a string literal
|
||||||
= note: `-D clippy::string-lit-as-bytes` implied by `-D warnings`
|
= note: `-D clippy::string-lit-as-bytes` implied by `-D warnings`
|
||||||
|
|
||||||
error: calling `as_bytes()` on a string literal
|
error: calling `as_bytes()` on a string literal
|
||||||
--> $DIR/strings.rs:65:18
|
--> $DIR/strings.rs:62:14
|
||||||
|
|
|
|
||||||
65 | let strify = stringify!(foobar).as_bytes();
|
62 | let bs = r###"raw string with three ### in it and some " ""###.as_bytes();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `bstringify!(foobar)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `br###"raw string with three ### in it and some " ""###`
|
||||||
|
|
||||||
error: manual implementation of an assign operation
|
error: calling `as_bytes()` on `include_str!(..)`
|
||||||
--> $DIR/strings.rs:75:7
|
--> $DIR/strings.rs:69:22
|
||||||
|
|
|
|
||||||
75 | ; x = x + 1;
|
69 | let includestr = include_str!("entry.rs").as_bytes();
|
||||||
| ^^^^^^^^^ help: replace it with: `x += 1`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("entry.rs")`
|
||||||
|
|
||||||
error: aborting due to 11 previous errors
|
error: aborting due to 11 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue