Skip to content

Commit 4147c9e

Browse files
committed
submodules: update clippy from 92612c9 to 37f5c1e
Changes: ```` Remove force-host and explain no-prefer-dynamic Escape a single quote in single_char_pattern hint cargo fmt Re-add tmp feature to compiletest Remove libtest from deps Re-allow clippy::identity_conversion in compiletest Use latest compiletest-rs Revert tests/compile-test.rs to 61aa5c9 Fix ICE in suspicious_else_formatting use a multispan for MANY_SINGLE_CHAR_NAMES Add missing `// run-pass` annotations to ICE tests Remove clippy_dev as dev-dependency NFC: fix typos rustup rust-lang/rust#59657 Add TransmutingNull Lint * Late Lint pass, catches: * One liner: 0 -> null -> transmute * One liner: std:null() -> transmute * Const (which resolves to null) -> transmute * UI Test case for Lint * Updated test for issue 3849, because now the lint that code generated is in Clippy. * Expanded `const.rs` miri-based Constant Folding code, to cover raw pointers Run rustfmt Set level of identity_conversion FP to warn Rustup to rust-lang/rust#58805 rustup 41316f0 Updated source to match with recent rustc `master` toolchain changes Fix dogfood error of question_mark lint fix Fix question_mark lint+test use `span_lint_and_sugg` in `explicit_counter_loop` Fix some test failures Hacky rustup run cargo fmt rustup rust-lang/rust#59096 Change explicit_counter_loop's message to add parentheses if necessary Change explicit_counter_loop's message to reflect original variable name cargo fmt Add rustfix tests for mistyped_literal_suffix lint Move some `unreadable_literal` ui tests to correct file Add implementation for the EarlyLintPass trait into the Adding Lints documentation. Add rust-toolchain for clippy_dev ````
1 parent ce14897 commit 4147c9e

File tree

92 files changed

+769
-293
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+769
-293
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,7 @@ All notable changes to this project will be documented in this file.
10221022
[`transmute_int_to_float`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_float
10231023
[`transmute_ptr_to_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ptr
10241024
[`transmute_ptr_to_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref
1025+
[`transmuting_null`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmuting_null
10251026
[`trivial_regex`]: https://rust-lang.github.io/rust-clippy/master/index.html#trivial_regex
10261027
[`trivially_copy_pass_by_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref
10271028
[`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,8 @@ semver = "0.9"
4545
rustc_tools_util = { version = "0.1.1", path = "rustc_tools_util"}
4646

4747
[dev-dependencies]
48-
clippy_dev = { version = "0.0.1", path = "clippy_dev" }
4948
cargo_metadata = "0.7.1"
50-
compiletest_rs = "0.3.19"
49+
compiletest_rs = { version = "0.3.21", features = ["tmp"] }
5150
lazy_static = "1.0"
5251
serde_derive = "1.0"
5352
clippy-mini-macro-test = { version = "0.2", path = "mini-macro" }

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
99

10-
[There are 297 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
10+
[There are 298 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
1111

1212
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
1313

clippy_dev/rust-toolchain

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
stable

clippy_lints/src/attrs.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@ impl LintPass for AttrPass {
208208
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
209209
fn check_attribute(&mut self, cx: &LateContext<'a, 'tcx>, attr: &'tcx Attribute) {
210210
if let Some(items) = &attr.meta_item_list() {
211-
if let Some(ident) = attr.ident_str() {
212-
match ident {
211+
if let Some(ident) = attr.ident() {
212+
match &*ident.as_str() {
213213
"allow" | "warn" | "deny" | "forbid" => {
214214
check_clippy_lint_names(cx, items);
215215
},
@@ -242,8 +242,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
242242

243243
for attr in &item.attrs {
244244
if let Some(lint_list) = &attr.meta_item_list() {
245-
if let Some(ident) = attr.ident_str() {
246-
match ident {
245+
if let Some(ident) = attr.ident() {
246+
match &*ident.as_str() {
247247
"allow" | "warn" | "deny" | "forbid" => {
248248
// whitelist `unused_imports` and `deprecated` for `use` items
249249
// and `unused_imports` for `extern crate` items with `macro_use`

clippy_lints/src/consts.rs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ pub enum Constant {
4141
Repeat(Box<Constant>, u64),
4242
/// A tuple of constants.
4343
Tuple(Vec<Constant>),
44+
/// A raw pointer.
45+
RawPtr(u128),
4446
/// A literal with syntax error.
4547
Err(Symbol),
4648
}
@@ -109,6 +111,9 @@ impl Hash for Constant {
109111
c.hash(state);
110112
l.hash(state);
111113
},
114+
Constant::RawPtr(u) => {
115+
u.hash(state);
116+
},
112117
Constant::Err(ref s) => {
113118
s.hash(state);
114119
},
@@ -192,7 +197,7 @@ pub fn constant_simple<'c, 'cc>(
192197
constant(lcx, tables, e).and_then(|(cst, res)| if res { None } else { Some(cst) })
193198
}
194199

195-
/// Creates a `ConstEvalLateContext` from the given `LateContext` and `TypeckTables`
200+
/// Creates a `ConstEvalLateContext` from the given `LateContext` and `TypeckTables`.
196201
pub fn constant_context<'c, 'cc>(
197202
lcx: &LateContext<'c, 'cc>,
198203
tables: &'c ty::TypeckTables<'cc>,
@@ -215,7 +220,7 @@ pub struct ConstEvalLateContext<'a, 'tcx: 'a> {
215220
}
216221

217222
impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
218-
/// simple constant folding: Insert an expression, get a constant or none.
223+
/// Simple constant folding: Insert an expression, get a constant or none.
219224
pub fn expr(&mut self, e: &Expr) -> Option<Constant> {
220225
match e.node {
221226
ExprKind::Path(ref qpath) => self.fetch_path(qpath, e.hir_id),
@@ -238,7 +243,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
238243
}),
239244
ExprKind::Binary(op, ref left, ref right) => self.binop(op, left, right),
240245
ExprKind::Call(ref callee, ref args) => {
241-
// We only handle a few const functions for now
246+
// We only handle a few const functions for now.
242247
if_chain! {
243248
if args.is_empty();
244249
if let ExprKind::Path(qpath) = &callee.node;
@@ -262,7 +267,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
262267
}
263268
}
264269
},
265-
// TODO: add other expressions
270+
// TODO: add other expressions.
266271
_ => None,
267272
}
268273
}
@@ -304,13 +309,13 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
304309
}
305310
}
306311

307-
/// create `Some(Vec![..])` of all constants, unless there is any
308-
/// non-constant part
312+
/// Create `Some(Vec![..])` of all constants, unless there is any
313+
/// non-constant part.
309314
fn multi(&mut self, vec: &[Expr]) -> Option<Vec<Constant>> {
310315
vec.iter().map(|elem| self.expr(elem)).collect::<Option<_>>()
311316
}
312317

313-
/// lookup a possibly constant expression from a ExprKind::Path
318+
/// Lookup a possibly constant expression from a ExprKind::Path.
314319
fn fetch_path(&mut self, qpath: &QPath, id: HirId) -> Option<Constant> {
315320
use rustc::mir::interpret::GlobalId;
316321

@@ -334,14 +339,14 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
334339
if ret.is_some() {
335340
self.needed_resolution = true;
336341
}
337-
return ret;
342+
ret
338343
},
339-
_ => {},
344+
// FIXME: cover all useable cases.
345+
_ => None,
340346
}
341-
None
342347
}
343348

344-
/// A block can only yield a constant if it only has one constant expression
349+
/// A block can only yield a constant if it only has one constant expression.
345350
fn block(&mut self, block: &Block) -> Option<Constant> {
346351
if block.stmts.is_empty() {
347352
block.expr.as_ref().and_then(|b| self.expr(b))
@@ -467,7 +472,13 @@ pub fn miri_to_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, result: &ty::Const<'
467472
ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits(
468473
b.try_into().expect("invalid f64 bit representation"),
469474
))),
470-
// FIXME: implement other conversion
475+
ty::RawPtr(type_and_mut) => {
476+
if let ty::Uint(_) = type_and_mut.ty.sty {
477+
return Some(Constant::RawPtr(b));
478+
}
479+
None
480+
},
481+
// FIXME: implement other conversions.
471482
_ => None,
472483
},
473484
ConstValue::Slice(Scalar::Ptr(ptr), n) => match result.ty.sty {
@@ -484,7 +495,7 @@ pub fn miri_to_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, result: &ty::Const<'
484495
},
485496
_ => None,
486497
},
487-
// FIXME: implement other conversions
498+
// FIXME: implement other conversions.
488499
_ => None,
489500
}
490501
}

clippy_lints/src/enum_glob_use.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@ impl LintPass for EnumGlobUse {
3939

4040
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EnumGlobUse {
4141
fn check_mod(&mut self, cx: &LateContext<'a, 'tcx>, m: &'tcx Mod, _: Span, _: HirId) {
42+
let map = cx.tcx.hir();
4243
// only check top level `use` statements
4344
for item in &m.item_ids {
44-
self.lint_item(cx, cx.tcx.hir().expect_item(item.id));
45+
self.lint_item(cx, map.expect_item(map.hir_to_node_id(item.id)));
4546
}
4647
}
4748
}

clippy_lints/src/formatting.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::utils::{differing_macro_contexts, in_macro, snippet_opt, span_note_and_lint};
2-
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
2+
use rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, LintPass};
33
use rustc::{declare_tool_lint, lint_array};
44
use syntax::ast;
55
use syntax::ptr::P;
@@ -150,6 +150,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &ast::Expr) {
150150
if (is_block(else_) || unsugar_if(else_).is_some())
151151
&& !differing_macro_contexts(then.span, else_.span)
152152
&& !in_macro(then.span)
153+
&& !in_external_macro(cx.sess, expr.span)
153154
{
154155
// workaround for rust-lang/rust#43081
155156
if expr.span.lo().0 == 0 && expr.span.hi().0 == 0 {

clippy_lints/src/functions.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,7 @@ impl<'a, 'tcx> Functions {
256256
hir_id: hir::HirId,
257257
) {
258258
let expr = &body.value;
259-
let node_id = cx.tcx.hir().hir_to_node_id(hir_id);
260-
if unsafety == hir::Unsafety::Normal && cx.access_levels.is_exported(node_id) {
259+
if unsafety == hir::Unsafety::Normal && cx.access_levels.is_exported(hir_id) {
261260
let raw_ptrs = iter_input_pats(decl, body)
262261
.zip(decl.inputs.iter())
263262
.filter_map(|(arg, ty)| raw_ptr_arg(arg, ty))

clippy_lints/src/len_zero.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,7 @@ fn check_trait_items(cx: &LateContext<'_, '_>, visited_trait: &Item, trait_items
148148
}
149149
}
150150

151-
let trait_node_id = cx.tcx.hir().hir_to_node_id(visited_trait.hir_id);
152-
153-
if cx.access_levels.is_exported(trait_node_id) && trait_items.iter().any(|i| is_named_self(cx, i, "len")) {
151+
if cx.access_levels.is_exported(visited_trait.hir_id) && trait_items.iter().any(|i| is_named_self(cx, i, "len")) {
154152
let mut current_and_super_traits = FxHashSet::default();
155153
let visited_trait_def_id = cx.tcx.hir().local_def_id_from_hir_id(visited_trait.hir_id);
156154
fill_trait_set(visited_trait_def_id, &mut current_and_super_traits, cx);
@@ -193,10 +191,7 @@ fn check_impl_items(cx: &LateContext<'_, '_>, item: &Item, impl_items: &[ImplIte
193191
}
194192

195193
let is_empty = if let Some(is_empty) = impl_items.iter().find(|i| is_named_self(cx, i, "is_empty")) {
196-
if cx
197-
.access_levels
198-
.is_exported(cx.tcx.hir().hir_to_node_id(is_empty.id.hir_id))
199-
{
194+
if cx.access_levels.is_exported(is_empty.id.hir_id) {
200195
return;
201196
} else {
202197
"a private"
@@ -206,7 +201,7 @@ fn check_impl_items(cx: &LateContext<'_, '_>, item: &Item, impl_items: &[ImplIte
206201
};
207202

208203
if let Some(i) = impl_items.iter().find(|i| is_named_self(cx, i, "len")) {
209-
if cx.access_levels.is_exported(cx.tcx.hir().hir_to_node_id(i.id.hir_id)) {
204+
if cx.access_levels.is_exported(i.id.hir_id) {
210205
let def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
211206
let ty = cx.tcx.type_of(def_id);
212207

clippy_lints/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ pub mod suspicious_trait_impl;
255255
pub mod swap;
256256
pub mod temporary_assignment;
257257
pub mod transmute;
258+
pub mod transmuting_null;
258259
pub mod trivially_copy_pass_by_ref;
259260
pub mod types;
260261
pub mod unicode;
@@ -279,7 +280,7 @@ mod reexport {
279280
///
280281
/// Pre-expansion lints run before any macro expansion has happened.
281282
///
282-
/// Note that due to the architechture of the compiler, currently `cfg_attr` attributes on crate
283+
/// Note that due to the architecture of the compiler, currently `cfg_attr` attributes on crate
283284
/// level (i.e `#![cfg_attr(...)]`) will still be expanded even when using a pre-expansion pass.
284285
///
285286
/// Used in `./src/driver.rs`.
@@ -570,6 +571,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
570571
reg.register_late_lint_pass(box types::RefToMut);
571572
reg.register_late_lint_pass(box assertions_on_constants::AssertionsOnConstants);
572573
reg.register_late_lint_pass(box missing_const_for_fn::MissingConstForFn);
574+
reg.register_late_lint_pass(box transmuting_null::Pass);
573575

574576
reg.register_lint_group("clippy::restriction", Some("clippy_restriction"), vec![
575577
arithmetic::FLOAT_ARITHMETIC,
@@ -841,6 +843,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
841843
transmute::TRANSMUTE_PTR_TO_REF,
842844
transmute::USELESS_TRANSMUTE,
843845
transmute::WRONG_TRANSMUTE,
846+
transmuting_null::TRANSMUTING_NULL,
844847
trivially_copy_pass_by_ref::TRIVIALLY_COPY_PASS_BY_REF,
845848
types::ABSURD_EXTREME_COMPARISONS,
846849
types::BORROWED_BOX,
@@ -1078,6 +1081,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
10781081
suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL,
10791082
swap::ALMOST_SWAPPED,
10801083
transmute::WRONG_TRANSMUTE,
1084+
transmuting_null::TRANSMUTING_NULL,
10811085
types::ABSURD_EXTREME_COMPARISONS,
10821086
types::CAST_PTR_ALIGNMENT,
10831087
types::CAST_REF_TO_MUT,

clippy_lints/src/lifetimes.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
356356
self.collect_anonymous_lifetimes(path, ty);
357357
},
358358
TyKind::Def(item, _) => {
359-
if let ItemKind::Existential(ref exist_ty) = self.cx.tcx.hir().expect_item(item.id).node {
359+
let map = self.cx.tcx.hir();
360+
if let ItemKind::Existential(ref exist_ty) = map.expect_item(map.hir_to_node_id(item.id)).node {
360361
for bound in &exist_ty.bounds {
361362
if let GenericBound::Outlives(_) = *bound {
362363
self.record(&None);

clippy_lints/src/loops.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@ fn check_for_loop<'a, 'tcx>(
777777
check_for_loop_range(cx, pat, arg, body, expr);
778778
check_for_loop_reverse_range(cx, arg, expr);
779779
check_for_loop_arg(cx, pat, arg, expr);
780-
check_for_loop_explicit_counter(cx, arg, body, expr);
780+
check_for_loop_explicit_counter(cx, pat, arg, body, expr);
781781
check_for_loop_over_map_kv(cx, pat, arg, body, expr);
782782
check_for_mut_range_bound(cx, arg, body);
783783
detect_manual_memcpy(cx, pat, arg, body, expr);
@@ -1453,6 +1453,7 @@ fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr) {
14531453

14541454
fn check_for_loop_explicit_counter<'a, 'tcx>(
14551455
cx: &LateContext<'a, 'tcx>,
1456+
pat: &'tcx Pat,
14561457
arg: &'tcx Expr,
14571458
body: &'tcx Expr,
14581459
expr: &'tcx Expr,
@@ -1489,16 +1490,31 @@ fn check_for_loop_explicit_counter<'a, 'tcx>(
14891490

14901491
if visitor2.state == VarState::Warn {
14911492
if let Some(name) = visitor2.name {
1492-
span_lint(
1493+
let mut applicability = Applicability::MachineApplicable;
1494+
span_lint_and_sugg(
14931495
cx,
14941496
EXPLICIT_COUNTER_LOOP,
14951497
expr.span,
1496-
&format!(
1497-
"the variable `{0}` is used as a loop counter. Consider using `for ({0}, \
1498-
item) in {1}.enumerate()` or similar iterators",
1498+
&format!("the variable `{}` is used as a loop counter.", name),
1499+
"consider using",
1500+
format!(
1501+
"for ({}, {}) in {}.enumerate()",
14991502
name,
1500-
snippet(cx, arg.span, "_")
1503+
snippet_with_applicability(cx, pat.span, "item", &mut applicability),
1504+
if higher::range(cx, arg).is_some() {
1505+
format!(
1506+
"({})",
1507+
snippet_with_applicability(cx, arg.span, "_", &mut applicability)
1508+
)
1509+
} else {
1510+
format!(
1511+
"{}",
1512+
sugg::Sugg::hir_with_applicability(cx, arg, "_", &mut applicability)
1513+
.maybe_par()
1514+
)
1515+
}
15011516
),
1517+
applicability,
15021518
);
15031519
}
15041520
}

clippy_lints/src/matches.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,11 +516,11 @@ fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
516516
for pat in &arm.pats {
517517
if let PatKind::Path(ref path) = pat.deref().node {
518518
if let QPath::Resolved(_, p) = path {
519-
missing_variants.retain(|e| e.did != p.def.def_id());
519+
missing_variants.retain(|e| e.ctor_def_id != Some(p.def.def_id()));
520520
}
521521
} else if let PatKind::TupleStruct(ref path, ..) = pat.deref().node {
522522
if let QPath::Resolved(_, p) = path {
523-
missing_variants.retain(|e| e.did != p.def.def_id());
523+
missing_variants.retain(|e| e.ctor_def_id != Some(p.def.def_id()));
524524
}
525525
}
526526
}
@@ -539,7 +539,7 @@ fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
539539
String::new()
540540
};
541541
// This path assumes that the enum type is imported into scope.
542-
format!("{}{}{}", ident_str, cx.tcx.def_path_str(v.did), suffix)
542+
format!("{}{}{}", ident_str, cx.tcx.def_path_str(v.def_id), suffix)
543543
})
544544
.collect();
545545

clippy_lints/src/methods/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -918,8 +918,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
918918
if let Some(first_arg) = iter_input_pats(&sig.decl, cx.tcx.hir().body(id)).next();
919919
if let hir::ItemKind::Impl(_, _, _, _, None, ref self_ty, _) = item.node;
920920
then {
921-
let node_id = cx.tcx.hir().hir_to_node_id(implitem.hir_id);
922-
if cx.access_levels.is_exported(node_id) {
921+
if cx.access_levels.is_exported(implitem.hir_id) {
923922
// check missing trait implementations
924923
for &(method_name, n_args, self_kind, out_type, trait_name) in &TRAIT_METHODS {
925924
if name == method_name &&
@@ -1636,7 +1635,7 @@ fn lint_get_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr, get_a
16361635

16371636
let mut span = expr.span;
16381637

1639-
// Handle the case where the result is immedately dereferenced
1638+
// Handle the case where the result is immediately dereferenced
16401639
// by not requiring ref and pulling the dereference into the
16411640
// suggestion.
16421641
if_chain! {
@@ -2144,7 +2143,8 @@ fn lint_single_char_pattern<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, _expr: &'tcx h
21442143
then {
21452144
let mut applicability = Applicability::MachineApplicable;
21462145
let snip = snippet_with_applicability(cx, arg.span, "..", &mut applicability);
2147-
let hint = format!("'{}'", &snip[1..snip.len() - 1]);
2146+
let c = &snip[1..snip.len() - 1];
2147+
let hint = format!("'{}'", if c == "'" { "\\'" } else { c });
21482148
span_lint_and_sugg(
21492149
cx,
21502150
SINGLE_CHAR_PATTERN,

0 commit comments

Comments
 (0)