Skip to content

Commit 12dff35

Browse files
committed
Deprecate string_to_string
1 parent b53ffe5 commit 12dff35

9 files changed

+10
-177
lines changed

clippy_lints/src/declared_lints.rs

-1
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
708708
crate::strings::STRING_FROM_UTF8_AS_BYTES_INFO,
709709
crate::strings::STRING_LIT_AS_BYTES_INFO,
710710
crate::strings::STRING_SLICE_INFO,
711-
crate::strings::STRING_TO_STRING_INFO,
712711
crate::strings::STR_TO_STRING_INFO,
713712
crate::strings::TRIM_SPLIT_WHITESPACE_INFO,
714713
crate::strlen_on_c_strings::STRLEN_ON_C_STRINGS_INFO,

clippy_lints/src/deprecated_lints.rs

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ declare_with_version! { DEPRECATED(DEPRECATED_VERSION): &[(&str, &str)] = &[
4242
("clippy::wrong_pub_self_convention", "`clippy::wrong_self_convention` now covers this case via the `avoid-breaking-exported-api` config"),
4343
#[clippy::version = "1.86.0"]
4444
("clippy::option_map_or_err_ok", "`clippy::manual_ok_or` covers this case"),
45+
#[clippy::version = "1.87.0"]
46+
("clippy::string_to_string", "`clippy:implicit_clone` and `clippy:map_clone` cover those cases"),
4547
// end deprecated lints. used by `cargo dev deprecate_lint`
4648
]}
4749

clippy_lints/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
822822
store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86IntelSyntax));
823823
store.register_late_pass(|_| Box::new(empty_drop::EmptyDrop));
824824
store.register_late_pass(|_| Box::new(strings::StrToString));
825-
store.register_late_pass(|_| Box::new(strings::StringToString));
826825
store.register_late_pass(|_| Box::new(zero_sized_map_values::ZeroSizedMapValues));
827826
store.register_late_pass(|_| Box::<vec_init_then_push::VecInitThenPush>::default());
828827
store.register_late_pass(|_| Box::new(redundant_slicing::RedundantSlicing));

clippy_lints/src/strings.rs

-109
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ use rustc_session::declare_lint_pass;
1414
use rustc_span::source_map::Spanned;
1515
use rustc_span::sym;
1616

17-
use std::ops::ControlFlow;
18-
1917
declare_clippy_lint! {
2018
/// ### What it does
2119
/// Checks for string appends of the form `x = x + y` (without
@@ -412,113 +410,6 @@ impl<'tcx> LateLintPass<'tcx> for StrToString {
412410
}
413411
}
414412

415-
declare_clippy_lint! {
416-
/// ### What it does
417-
/// This lint checks for `.to_string()` method calls on values of type `String`.
418-
///
419-
/// ### Why restrict this?
420-
/// The `to_string` method is also used on other types to convert them to a string.
421-
/// When called on a `String` it only clones the `String`, which can be more specifically
422-
/// expressed with `.clone()`.
423-
///
424-
/// ### Example
425-
/// ```no_run
426-
/// let msg = String::from("Hello World");
427-
/// let _ = msg.to_string();
428-
/// ```
429-
/// Use instead:
430-
/// ```no_run
431-
/// let msg = String::from("Hello World");
432-
/// let _ = msg.clone();
433-
/// ```
434-
#[clippy::version = "pre 1.29.0"]
435-
pub STRING_TO_STRING,
436-
restriction,
437-
"using `to_string()` on a `String`, which should be `clone()`"
438-
}
439-
440-
declare_lint_pass!(StringToString => [STRING_TO_STRING]);
441-
442-
fn is_parent_map_like(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<rustc_span::Span> {
443-
if let Some(parent_expr) = get_parent_expr(cx, expr)
444-
&& let ExprKind::MethodCall(name, _, _, parent_span) = parent_expr.kind
445-
&& name.ident.name == sym::map
446-
&& let Some(caller_def_id) = cx.typeck_results().type_dependent_def_id(parent_expr.hir_id)
447-
&& (clippy_utils::is_diag_item_method(cx, caller_def_id, sym::Result)
448-
|| clippy_utils::is_diag_item_method(cx, caller_def_id, sym::Option)
449-
|| clippy_utils::is_diag_trait_item(cx, caller_def_id, sym::Iterator))
450-
{
451-
Some(parent_span)
452-
} else {
453-
None
454-
}
455-
}
456-
457-
fn is_called_from_map_like(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<rustc_span::Span> {
458-
// Look for a closure as parent of `expr`, discarding simple blocks
459-
let parent_closure = cx
460-
.tcx
461-
.hir_parent_iter(expr.hir_id)
462-
.try_fold(expr.hir_id, |child_hir_id, (_, node)| match node {
463-
// Check that the child expression is the only expression in the block
464-
Node::Block(block) if block.stmts.is_empty() && block.expr.map(|e| e.hir_id) == Some(child_hir_id) => {
465-
ControlFlow::Continue(block.hir_id)
466-
},
467-
Node::Expr(expr) if matches!(expr.kind, ExprKind::Block(..)) => ControlFlow::Continue(expr.hir_id),
468-
Node::Expr(expr) if matches!(expr.kind, ExprKind::Closure(_)) => ControlFlow::Break(Some(expr)),
469-
_ => ControlFlow::Break(None),
470-
})
471-
.break_value()?;
472-
is_parent_map_like(cx, parent_closure?)
473-
}
474-
475-
fn suggest_cloned_string_to_string(cx: &LateContext<'_>, span: rustc_span::Span) {
476-
span_lint_and_sugg(
477-
cx,
478-
STRING_TO_STRING,
479-
span,
480-
"`to_string()` called on a `String`",
481-
"try",
482-
"cloned()".to_string(),
483-
Applicability::MachineApplicable,
484-
);
485-
}
486-
487-
impl<'tcx> LateLintPass<'tcx> for StringToString {
488-
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
489-
if expr.span.from_expansion() {
490-
return;
491-
}
492-
493-
match &expr.kind {
494-
ExprKind::MethodCall(path, self_arg, [], _) => {
495-
if path.ident.name == sym::to_string
496-
&& let ty = cx.typeck_results().expr_ty(self_arg)
497-
&& is_type_lang_item(cx, ty.peel_refs(), LangItem::String)
498-
&& let Some(parent_span) = is_called_from_map_like(cx, expr)
499-
{
500-
suggest_cloned_string_to_string(cx, parent_span);
501-
}
502-
},
503-
ExprKind::Path(QPath::TypeRelative(ty, segment)) => {
504-
if segment.ident.name == sym::to_string
505-
&& let rustc_hir::TyKind::Path(QPath::Resolved(_, path)) = ty.peel_refs().kind
506-
&& let rustc_hir::def::Res::Def(_, def_id) = path.res
507-
&& cx
508-
.tcx
509-
.lang_items()
510-
.get(LangItem::String)
511-
.is_some_and(|lang_id| lang_id == def_id)
512-
&& let Some(parent_span) = is_parent_map_like(cx, expr)
513-
{
514-
suggest_cloned_string_to_string(cx, parent_span);
515-
}
516-
},
517-
_ => {},
518-
}
519-
}
520-
}
521-
522413
declare_clippy_lint! {
523414
/// ### What it does
524415
/// Warns about calling `str::trim` (or variants) before `str::split_whitespace`.

tests/ui/deprecated.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@
1616
#![warn(clippy::pub_enum_variant_names)] //~ ERROR: lint `clippy::pub_enum_variant_names`
1717
#![warn(clippy::wrong_pub_self_convention)] //~ ERROR: lint `clippy::wrong_pub_self_convention`
1818
#![warn(clippy::option_map_or_err_ok)] //~ ERROR: lint `clippy::option_map_or_err_ok`
19+
#![warn(clippy::string_to_string)] //~ ERROR: lint `clippy::string_to_string`
1920

2021
fn main() {}

tests/ui/deprecated.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,11 @@ error: lint `clippy::option_map_or_err_ok` has been removed: `clippy::manual_ok_
8585
LL | #![warn(clippy::option_map_or_err_ok)]
8686
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8787

88-
error: aborting due to 14 previous errors
88+
error: lint `clippy::string_to_string` has been removed: `clippy:implicit_clone` and `clippy:map_clone` cover those cases
89+
--> tests/ui/deprecated.rs:19:9
90+
|
91+
LL | #![warn(clippy::string_to_string)]
92+
| ^^^^^^^^^^^^^^^^^^^^^^^^
93+
94+
error: aborting due to 15 previous errors
8995

tests/ui/string_to_string.fixed

-21
This file was deleted.

tests/ui/string_to_string.rs

-21
This file was deleted.

tests/ui/string_to_string.stderr

-23
This file was deleted.

0 commit comments

Comments
 (0)