Skip to content

Commit b09d9d6

Browse files
committed
Deprecate string_to_string
1 parent 94ca054 commit b09d9d6

9 files changed

+15
-182
lines changed

clippy_lints/src/declared_lints.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
683683
crate::strings::STRING_FROM_UTF8_AS_BYTES_INFO,
684684
crate::strings::STRING_LIT_AS_BYTES_INFO,
685685
crate::strings::STRING_SLICE_INFO,
686-
crate::strings::STRING_TO_STRING_INFO,
687686
crate::strings::STR_TO_STRING_INFO,
688687
crate::strings::TRIM_SPLIT_WHITESPACE_INFO,
689688
crate::strlen_on_c_strings::STRLEN_ON_C_STRINGS_INFO,

clippy_lints/src/deprecated_lints.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ declare_with_version! { DEPRECATED(DEPRECATED_VERSION) = [
3434
("clippy::replace_consts", "`min_value` and `max_value` are now deprecated"),
3535
#[clippy::version = "pre 1.29.0"]
3636
("clippy::should_assert_eq", "`assert!(a == b)` can now print the values the same way `assert_eq!(a, b) can"),
37+
#[clippy::version = "1.87.0"]
38+
("clippy::string_to_string", "`clippy:implicit_clone` and `clippy:map_clone` cover those cases"),
3739
#[clippy::version = "pre 1.29.0"]
3840
("clippy::unsafe_vector_initialization", "the suggested alternative could be substantially slower"),
3941
#[clippy::version = "pre 1.29.0"]

clippy_lints/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
782782
store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86IntelSyntax));
783783
store.register_late_pass(|_| Box::new(empty_drop::EmptyDrop));
784784
store.register_late_pass(|_| Box::new(strings::StrToString));
785-
store.register_late_pass(|_| Box::new(strings::StringToString));
786785
store.register_late_pass(|_| Box::new(zero_sized_map_values::ZeroSizedMapValues));
787786
store.register_late_pass(|_| Box::<vec_init_then_push::VecInitThenPush>::default());
788787
store.register_late_pass(|_| Box::new(redundant_slicing::RedundantSlicing));

clippy_lints/src/strings.rs

Lines changed: 0 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ use rustc_middle::ty;
1313
use rustc_session::declare_lint_pass;
1414
use rustc_span::source_map::Spanned;
1515

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

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

tests/ui/deprecated.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#![warn(clippy::regex_macro)] //~ ERROR: lint `clippy::regex_macro`
1313
#![warn(clippy::replace_consts)] //~ ERROR: lint `clippy::replace_consts`
1414
#![warn(clippy::should_assert_eq)] //~ ERROR: lint `clippy::should_assert_eq`
15+
#![warn(clippy::string_to_string)] //~ ERROR: lint `clippy::string_to_string`
1516
#![warn(clippy::unsafe_vector_initialization)] //~ ERROR: lint `clippy::unsafe_vector_initialization`
1617
#![warn(clippy::unstable_as_mut_slice)] //~ ERROR: lint `clippy::unstable_as_mut_slice`
1718
#![warn(clippy::unstable_as_slice)] //~ ERROR: lint `clippy::unstable_as_slice`

tests/ui/deprecated.stderr

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,35 +61,41 @@ error: lint `clippy::should_assert_eq` has been removed: `assert!(a == b)` can n
6161
LL | #![warn(clippy::should_assert_eq)]
6262
| ^^^^^^^^^^^^^^^^^^^^^^^^
6363

64-
error: lint `clippy::unsafe_vector_initialization` has been removed: the suggested alternative could be substantially slower
64+
error: lint `clippy::string_to_string` has been removed: `clippy:implicit_clone` and `clippy:map_clone` cover those cases
6565
--> tests/ui/deprecated.rs:15:9
6666
|
67+
LL | #![warn(clippy::string_to_string)]
68+
| ^^^^^^^^^^^^^^^^^^^^^^^^
69+
70+
error: lint `clippy::unsafe_vector_initialization` has been removed: the suggested alternative could be substantially slower
71+
--> tests/ui/deprecated.rs:16:9
72+
|
6773
LL | #![warn(clippy::unsafe_vector_initialization)]
6874
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6975

7076
error: lint `clippy::unstable_as_mut_slice` has been removed: `Vec::as_mut_slice` is now stable
71-
--> tests/ui/deprecated.rs:16:9
77+
--> tests/ui/deprecated.rs:17:9
7278
|
7379
LL | #![warn(clippy::unstable_as_mut_slice)]
7480
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7581

7682
error: lint `clippy::unstable_as_slice` has been removed: `Vec::as_slice` is now stable
77-
--> tests/ui/deprecated.rs:17:9
83+
--> tests/ui/deprecated.rs:18:9
7884
|
7985
LL | #![warn(clippy::unstable_as_slice)]
8086
| ^^^^^^^^^^^^^^^^^^^^^^^^^
8187

8288
error: lint `clippy::unused_collect` has been removed: `Iterator::collect` is now marked as `#[must_use]`
83-
--> tests/ui/deprecated.rs:18:9
89+
--> tests/ui/deprecated.rs:19:9
8490
|
8591
LL | #![warn(clippy::unused_collect)]
8692
| ^^^^^^^^^^^^^^^^^^^^^^
8793

8894
error: lint `clippy::wrong_pub_self_convention` has been removed: `clippy::wrong_self_convention` now covers this case via the `avoid-breaking-exported-api` config
89-
--> tests/ui/deprecated.rs:19:9
95+
--> tests/ui/deprecated.rs:20:9
9096
|
9197
LL | #![warn(clippy::wrong_pub_self_convention)]
9298
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9399

94-
error: aborting due to 15 previous errors
100+
error: aborting due to 16 previous errors
95101

tests/ui/string_to_string.fixed

Lines changed: 0 additions & 21 deletions
This file was deleted.

tests/ui/string_to_string.rs

Lines changed: 0 additions & 21 deletions
This file was deleted.

tests/ui/string_to_string.stderr

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)