Skip to content

<T as Into<T>>::into lint#129249

Open
estebank wants to merge 6 commits into
rust-lang:mainfrom
estebank:useless-into
Open

<T as Into<T>>::into lint#129249
estebank wants to merge 6 commits into
rust-lang:mainfrom
estebank:useless-into

Conversation

@estebank
Copy link
Copy Markdown
Contributor

@estebank estebank commented Aug 18, 2024

View all comments

Add two lints, very similar to clippy::useless_conversion, detecting when .into() is being called unnecessarily. We present two separate lints, one that triggers inside of macros, because it is common for macros to have .into() calls to make the caller side easier to use. In those cases people should still use the fully-qualified path instead,
but allow them to silence that lint without silencing the more general, more likely to be problematic case.

This lint allows us to protect developers from the semver-hazard that time 0.3.34 encountered, where a std change caused a valid method chain to start producing inference errors. This is explicitly allowed by the Rust project's backwards compatibility guarantees (inference is not included in them), which means that relying on the blanket impl Into is a problem.

The lint as implemented has false negatives: because of the way type aliases are handled by the type system, we can't know whether let _: i32 = 0i32.into() corresponds to a call on i32 or a call on a type alias that is i32 only on some platforms (like #[cfg(..)] type Int = i32;). To avoid false positives, we keep track of type aliases that have been imported in the local crate and mark their types for exclusion. This means that calling let _: i32 = Int::into(0i32); will not be linted against even though it should.


Running crater to see how common that pattern is. The Lint would have to be at most warn-by-default because there are a handful of cases detected that are actually perfectly reasonable (type aliases with per-platform cfg, or macros) which are now at best half-heartedly handled.

I've detected a handful of cases where we're calling .into() unnecessarily in the rustc codebase as well, and changed those.

CC #127343.

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Aug 18, 2024

r? @chenyukang

rustbot has assigned @chenyukang.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added O-unix Operating system: Unix-like S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Aug 18, 2024
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Aug 18, 2024

Some changes occurred to the CTFE / Miri engine

cc @rust-lang/miri

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

@estebank
Copy link
Copy Markdown
Contributor Author

@bors try @craterbot check

@estebank
Copy link
Copy Markdown
Contributor Author

@bors try

@bors

This comment was marked as outdated.

Comment thread compiler/rustc_lint/src/builtin.rs
@estebank
Copy link
Copy Markdown
Contributor Author

@bors try

@bors
Copy link
Copy Markdown
Collaborator

bors commented Aug 18, 2024

⌛ Trying commit 2aaca93 with merge 622c05b...

bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 18, 2024
[Experimental] `<T as Into<T>>::into` lint

Running crater to see how common that pattern is. The Lint would have to be at most warn-by-default because there are a handful of cases detected that are actually perfectly reasonable (`type` aliases with per-platform `cfg`, or macros) which are now at best half-heartedly handled.

I've detected a handful of cases where we're calling `.into()` unnecessarily in the `rustc` codebase as well, and changed those.
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Copy Markdown
Collaborator

bors commented Aug 18, 2024

💔 Test failed - checks-actions

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 18, 2024
@matthiaskrgr
Copy link
Copy Markdown
Member

matthiaskrgr commented Aug 18, 2024

🤔 looks like you are reimplementing a subset of https://rust-lang.github.io/rust-clippy/master/index.html#/useless_conversion ?

edit: spoiler
at 21:37:58 ❯ ./x.py clippy -Aclippy::all -Wclippy::useless_conversion
Building bootstrap
    Finished `dev` profile [unoptimized] target(s) in 0.04s
Linting stage0 library {alloc, core, panic_abort, panic_unwind, proc_macro, std, sysroot, test, unwind} (x86_64-unknown-linux-gnu)
   Compiling compiler_builtins v0.1.118
    Checking core v0.0.0 (/home/matthias/vcs/github/rust/library/core)
   Compiling libc v0.2.155
   Compiling memchr v2.5.0
   Compiling std v0.0.0 (/home/matthias/vcs/github/rust/library/std)
    Checking rustc-std-workspace-core v1.99.0 (/home/matthias/vcs/github/rust/library/rustc-std-workspace-core)
    Checking alloc v0.0.0 (/home/matthias/vcs/github/rust/library/alloc)
    Checking cfg-if v1.0.0
    Checking adler v1.0.2
    Checking rustc-demangle v0.1.24
    Checking unwind v0.0.0 (/home/matthias/vcs/github/rust/library/unwind)
    Checking rustc-std-workspace-alloc v1.99.0 (/home/matthias/vcs/github/rust/library/rustc-std-workspace-alloc)
    Checking panic_abort v0.0.0 (/home/matthias/vcs/github/rust/library/panic_abort)
    Checking panic_unwind v0.0.0 (/home/matthias/vcs/github/rust/library/panic_unwind)
    Checking gimli v0.29.0
    Checking hashbrown v0.14.5
    Checking object v0.36.2
    Checking miniz_oxide v0.7.4
    Checking std_detect v0.1.5 (/home/matthias/vcs/github/rust/library/stdarch/crates/std_detect)
    Checking addr2line v0.22.0
warning: useless conversion to the same type: `i32`
   --> std/src/os/unix/process.rs:333:9
    |
333 |         self.as_inner().into_raw().into()
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `self.as_inner().into_raw()`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
    = note: `-D clippy::useless-conversion` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::useless_conversion)]`

warning: useless conversion to the same type: `os::fd::owned::OwnedFd`
   --> std/src/os/fd/owned.rs:331:9
    |
331 |         tcp_stream.into_inner().into_socket().into_inner().into_inner().into()
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `tcp_stream.into_inner().into_socket().into_inner().into_inner()`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: useless conversion to the same type: `os::fd::owned::OwnedFd`
   --> std/src/os/fd/owned.rs:358:9
    |
358 |         tcp_listener.into_inner().into_socket().into_inner().into_inner().into()
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `tcp_listener.into_inner().into_socket().into_inner().into_inner()`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: useless conversion to the same type: `os::fd::owned::OwnedFd`
   --> std/src/os/fd/owned.rs:385:9
    |
385 |         udp_socket.into_inner().into_socket().into_inner().into_inner().into()
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `udp_socket.into_inner().into_socket().into_inner().into_inner()`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: useless conversion to the same type: `usize`
   --> std/src/sys/pal/unix/process/process_unix.rs:307:37
    |
307 |                 cvt(libc::setgroups(_g.len().try_into().unwrap(), _g.as_ptr()))?;
    |                                     ^^^^^^^^^^^^^^^^^^^
    |
    = help: consider removing `.try_into()`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: useless conversion to the same type: `io::error::Error`
   --> std/src/sys/pal/unix/process/process_unix.rs:328:40
    |
328 | ...                   return Err(e.into());
    |                                  ^^^^^^^^ help: consider removing `.into()`: `e`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: useless conversion to the same type: `i64`
   --> std/src/sys/pal/unix/time.rs:196:21
    |
196 |             tv_sec: self.tv_sec.try_into().ok()?,
    |                     ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider removing `.try_into()`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: useless conversion to the same type: `ffi::os_str::OsString`
  --> std/src/sys_common/process.rs:38:31
   |
38 |                 result.insert(k.into(), v);
   |                               ^^^^^^^^ help: consider removing `.into()`: `k`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: `std` (lib) generated 8 warnings (run `cargo clippy --fix --lib -p std` to apply 6 suggestions)
    Checking rustc-std-workspace-std v1.99.0 (/home/matthias/vcs/github/rust/library/rustc-std-workspace-std)
    Checking proc_macro v0.0.0 (/home/matthias/vcs/github/rust/library/proc_macro)
    Checking unicode-width v0.1.13
    Checking getopts v0.2.21
    Checking test v0.0.0 (/home/matthias/vcs/github/rust/library/test)
    Checking sysroot v0.0.0 (/home/matthias/vcs/github/rust/library/sysroot)
    Finished `release` profile [optimized + debuginfo] target(s) in 35.62s
Checking stage0 library artifacts (x86_64-unknown-linux-gnu)
   Compiling compiler_builtins v0.1.118
   Compiling libc v0.2.155
   Compiling memchr v2.5.0
   Compiling std v0.0.0 (/home/matthias/vcs/github/rust/library/std)
    Checking alloc v0.0.0 (/home/matthias/vcs/github/rust/library/alloc)
    Checking cfg-if v1.0.0
    Checking adler v1.0.2
    Checking rustc-demangle v0.1.24
    Checking unwind v0.0.0 (/home/matthias/vcs/github/rust/library/unwind)
    Checking rustc-std-workspace-alloc v1.99.0 (/home/matthias/vcs/github/rust/library/rustc-std-workspace-alloc)
    Checking panic_unwind v0.0.0 (/home/matthias/vcs/github/rust/library/panic_unwind)
    Checking panic_abort v0.0.0 (/home/matthias/vcs/github/rust/library/panic_abort)
    Checking gimli v0.29.0
    Checking std_detect v0.1.5 (/home/matthias/vcs/github/rust/library/stdarch/crates/std_detect)
    Checking object v0.36.2
    Checking miniz_oxide v0.7.4
    Checking hashbrown v0.14.5
    Checking addr2line v0.22.0
    Checking rustc-std-workspace-std v1.99.0 (/home/matthias/vcs/github/rust/library/rustc-std-workspace-std)
    Checking proc_macro v0.0.0 (/home/matthias/vcs/github/rust/library/proc_macro)
    Checking unicode-width v0.1.13
    Checking getopts v0.2.21
    Checking test v0.0.0 (/home/matthias/vcs/github/rust/library/test)
    Checking sysroot v0.0.0 (/home/matthias/vcs/github/rust/library/sysroot)
    Finished `release` profile [optimized + debuginfo] target(s) in 7.67s
Linting stage0 compiler {rustc-main, rustc_abi, rustc_arena, rustc_ast, rustc_ast_ir, rustc_ast_lowering, rustc_ast_passes, rustc_ast_pretty, rustc_attr, rustc_baked_icu_data, rustc_borrowck, rustc_builtin_macros, rustc_codegen_llvm, rustc_codegen_ssa, rustc_const_eval, rustc_data_structures, rustc_driver, rustc_driver_impl, rustc_error_codes, rustc_error_messages, rustc_errors, rustc_expand, rustc_feature, rustc_fluent_macro, rustc_fs_util, rustc_graphviz, rustc_hir, rustc_hir_analysis, rustc_hir_pretty, rustc_hir_typeck, rustc_incremental, rustc_index, rustc_index_macros, rustc_infer, rustc_interface, rustc_lexer, rustc_lint, rustc_lint_defs, rustc_llvm, rustc_log, rustc_macros, rustc_metadata, rustc_middle, rustc_mir_build, rustc_mir_dataflow, rustc_mir_transform, rustc_monomorphize, rustc_next_trait_solver, rustc_parse, rustc_parse_format, rustc_passes, rustc_pattern_analysis, rustc_privacy, rustc_query_impl, rustc_query_system, rustc_resolve, rustc_sanitizers, rustc_serialize, rustc_session, rustc_smir, rustc_span, rustc_symbol_mangling, rustc_target, rustc_trait_selection, rustc_traits, rustc_transmute, rustc_ty_utils, rustc_type_ir, rustc_type_ir_macros, stable_mir} (x86_64-unknown-linux-gnu)
    Checking cfg-if v1.0.0
    Checking once_cell v1.19.0
    Checking stable_deref_trait v1.2.0
    Checking smallvec v1.13.2
    Checking either v1.12.0
    Checking zerocopy v0.7.34
    Checking allocator-api2 v0.2.18
    Checking equivalent v1.0.1
    Checking bitflags v2.5.0
    Checking libc v0.2.155
    Checking crossbeam-utils v0.8.20
    Checking memchr v2.5.0
    Checking log v0.4.21
    Checking scopeguard v1.2.0
    Checking typenum v1.17.0
    Checking pin-project-lite v0.2.14
    Checking rustc-hash v1.1.0
    Checking zerofrom v0.1.4
    Checking thin-vec v0.2.13
    Checking lock_api v0.4.12
    Checking linux-raw-sys v0.4.14
    Checking arrayvec v0.7.4
    Checking tracing-core v0.1.30
    Checking psm v0.1.21
    Checking fastrand v2.1.0
    Checking yoke v0.7.4
    Checking ena v0.14.3
    Checking rustc_arena v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_arena)
    Checking elsa v1.7.1
    Checking cpufeatures v0.2.12
    Checking unicode-width v0.1.13
    Checking ahash v0.8.11
    Checking rustc_graphviz v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_graphviz)
    Checking itoa v1.0.11
    Checking rustc-stable-hash v0.1.0
    Checking scoped-tls v1.0.1
    Checking ppv-lite86 v0.2.17
    Checking crc32fast v1.4.2
    Checking zerovec v0.10.2
    Checking writeable v0.5.5
    Checking crossbeam-epoch v0.9.18
    Checking crossbeam-channel v0.5.13
    Checking litemap v0.7.3
    Checking serde v1.0.203
    Checking unicode-xid v0.2.4
    Checking unicode-properties v0.1.1
    Checking tracing v0.1.37
    Checking rustix v0.38.34
    Checking wasmparser v0.214.0
    Checking hashbrown v0.14.5
    Checking icu_locid_transform_data v1.5.0
    Checking ryu v1.0.18
    Checking thiserror v1.0.61
    Checking rustc_lexer v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_lexer)
    Checking regex-automata v0.2.0
    Checking generic-array v0.14.7
    Checking type-map v0.5.0
    Checking rustc_fs_util v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_fs_util)
    Checking self_cell v1.0.4
    Checking crossbeam-deque v0.8.5
    Checking icu_list_data v1.5.0
    Checking fluent-syntax v0.11.1
    Checking odht v0.3.1
    Checking self_cell v0.10.3
    Checking itertools v0.12.1
    Checking anstyle v1.0.7
    Checking rustc_error_codes v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_error_codes)
    Checking termcolor v1.4.1
    Checking getopts v0.2.21
    Checking memoffset v0.9.1
    Checking bitflags v1.3.2
    Checking datafrog v2.0.1
    Checking rustc_apfloat v0.2.0+llvm-462a31f5a5ab
    Checking field-offset v0.3.6
    Checking annotate-snippets v0.10.2
    Checking tinyvec_macros v0.1.1
    Checking aho-corasick v1.1.3
    Checking regex-syntax v0.7.5
    Checking static_assertions v1.1.0
    Checking tinyvec v1.6.0
    Checking adler v1.0.2
    Checking byteorder v1.5.0
    Checking block-buffer v0.10.4
    Checking crypto-common v0.1.6
    Checking polonius-engine v0.13.0
    Checking miniz_oxide v0.7.4
    Checking unicode-script v0.5.6
    Checking num_cpus v1.16.0
    Checking parking_lot_core v0.9.10
    Checking tinystr v0.7.6
    Checking digest v0.10.7
    Checking perf-event-open-sys v3.0.0
    Checking memmap2 v0.2.3
    Checking rustc-rayon-core v0.5.0
    Checking parking_lot v0.12.3
    Checking jobserver v0.1.31
    Checking stacker v0.1.15
    Checking getrandom v0.2.15
    Checking sha2 v0.10.8
    Checking md-5 v0.10.6
    Checking sha1 v0.10.6
    Checking unic-langid-impl v0.9.5
    Checking measureme v11.0.1
    Checking icu_locid v1.5.0
    Checking rand_core v0.6.4
    Checking termize v0.1.1
    Checking snap v1.1.1
    Checking flate2 v1.0.30
    Checking libloading v0.8.3
    Checking unic-langid-macros v0.9.5
    Checking rand_chacha v0.3.1
    Checking rand_xoshiro v0.6.0
    Checking unic-langid v0.9.5
    Checking regex-syntax v0.6.29
    Checking unicode-normalization v0.1.23
    Checking rustc-rayon v0.5.0
    Checking fluent-langneg v0.13.0
    Checking intl_pluralrules v7.0.2
    Checking intl-memoizer v0.5.2
    Checking rustc-demangle v0.1.24
    Checking rand v0.8.5
    Checking lazy_static v1.5.0
    Checking punycode v0.4.1
    Checking tempfile v3.10.1
    Checking leb128 v0.2.5
    Checking overload v0.1.1
    Checking sharded-slab v0.1.7
    Checking unicase v2.7.0
    Checking wasm-encoder v0.210.0
    Checking thread_local v1.1.8
    Checking nu-ansi-term v0.46.0
    Checking icu_provider v1.5.0
    Checking fluent-bundle v0.15.3
    Checking pathdiff v0.2.1
    Checking cc v1.0.99
    Checking pulldown-cmark-escape v0.11.0
    Checking rustc_llvm v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_llvm)
    Checking tracing-log v0.2.0
    Checking unicode-security v0.1.1
    Checking powerfmt v0.2.0
    Checking pulldown-cmark v0.11.0
    Checking nu-ansi-term v0.50.0
    Checking nix v0.28.0
    Checking deranged v0.3.11
    Checking icu_locid_transform v1.5.0
    Checking time-core v0.1.2
    Checking num-conv v0.1.0
    Checking twox-hash v1.6.3
    Checking shlex v1.3.0
    Checking regex-automata v0.3.7
    Checking ruzstd v0.5.0
    Checking serde_json v1.0.117
    Checking gsgdt v0.1.2
    Checking stable_mir v0.1.0-preview (/home/matthias/vcs/github/rust/compiler/stable_mir)
    Checking icu_list v1.5.0
    Checking icu_provider_adapters v1.5.0
    Checking time v0.3.36
    Checking ctrlc v3.4.4
    Checking regex-automata v0.1.10
    Checking indexmap v2.4.0
    Checking rustc_baked_icu_data v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_baked_icu_data)
    Checking matchers v0.1.0
    Checking rustc_serialize v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_serialize)
    Checking object v0.36.2
    Checking object v0.32.2
    Checking gimli v0.28.1
    Checking regex v1.9.4
    Checking rustc_index v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_index)
    Checking tracing-subscriber v0.3.18
    Checking rustc_data_structures v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_data_structures)
    Checking rustc_parse_format v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_parse_format)
    Checking tracing-tree v0.3.1
    Checking rustc_log v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_log)
    Checking rustc_span v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_span)
    Checking rustc_abi v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_abi)
    Checking thorin-dwp v0.7.0
    Checking ar_archive_writer v0.4.0
    Checking rustc_ast_ir v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_ast_ir)
    Checking rustc_feature v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_feature)
    Checking rustc_error_messages v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_error_messages)
    Checking rustc_ast v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_ast)
    Checking rustc_type_ir v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_type_ir)
    Checking rustc_target v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_target)
warning: useless conversion to the same type: `ast::StaticItem`
    --> compiler/rustc_ast/src/ast.rs:3467:43
     |
3467 |                 ItemKind::Static(Box::new(static_foreign_item.into()))
     |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `static_foreign_item`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
     = note: `-D clippy::useless-conversion` implied by `-D warnings`
     = help: to override `-D warnings` add `#[allow(clippy::useless_conversion)]`

warning: useless conversion to the same type: `ast::StaticItem`
    --> compiler/rustc_ast/src/ast.rs:3482:50
     |
3482 |                 ForeignItemKind::Static(Box::new(static_item.into()))
     |                                                  ^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `static_item`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: `rustc_ast` (lib) generated 2 warnings (run `cargo clippy --fix --lib -p rustc_ast` to apply 2 suggestions)
    Checking rustc_ast_pretty v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_ast_pretty)
    Checking rustc_next_trait_solver v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_next_trait_solver)
warning: useless conversion to the same type: `impl std::iter::Iterator<Item = <I as rustc_type_ir::Interner>::DefId>`
   --> compiler/rustc_next_trait_solver/src/solve/trait_goals.rs:878:17
    |
878 | /                 elaborate::supertrait_def_ids(self.cx(), principal_def_id)
879 | |                     .into_iter()
    | |________________________________^ help: consider removing `.into_iter()`: `elaborate::supertrait_def_ids(self.cx(), principal_def_id)`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
    = note: `-D clippy::useless-conversion` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::useless_conversion)]`

warning: `rustc_next_trait_solver` (lib) generated 1 warning (run `cargo clippy --fix --lib -p rustc_next_trait_solver` to apply 1 suggestion)
    Checking rustc_hir v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_hir)
    Checking rustc_lint_defs v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_lint_defs)
    Checking rustc_hir_pretty v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_hir_pretty)
    Checking rustc_errors v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_errors)
warning: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
   --> compiler/rustc_errors/src/diagnostic.rs:709:20
    |
709 |         msg.extend(expected.0.into_iter());
    |                    ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `expected.0`
    |
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
   --> /home/matthias/vcs/github/rust/library/core/src/iter/traits/collect.rs:450:18
    |
450 |     fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T);
    |                  ^^^^^^^^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
    = note: `-D clippy::useless-conversion` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::useless_conversion)]`

warning: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
   --> compiler/rustc_errors/src/diagnostic.rs:712:20
    |
712 |         msg.extend(found.0.into_iter());
    |                    ^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `found.0`
    |
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
   --> /home/matthias/vcs/github/rust/library/core/src/iter/traits/collect.rs:450:18
    |
450 |     fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T);
    |                  ^^^^^^^^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: `rustc_errors` (lib) generated 2 warnings (run `cargo clippy --fix --lib -p rustc_errors` to apply 2 suggestions)
    Checking rustc_session v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_session)
    Checking rustc_attr v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_attr)
    Checking rustc_query_system v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_query_system)
    Checking rustc_parse v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_parse)
    Checking rustc_middle v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_middle)
warning: useless conversion to the same type: `rustc_ast::Recovered`
    --> compiler/rustc_parse/src/parser/item.rs:1589:58
     |
1589 |                 VariantData::Struct { fields, recovered: recovered.into() }
     |                                                          ^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `recovered`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
     = note: `-D clippy::useless-conversion` implied by `-D warnings`
     = help: to override `-D warnings` add `#[allow(clippy::useless_conversion)]`

warning: useless conversion to the same type: `rustc_ast::Recovered`
    --> compiler/rustc_parse/src/parser/item.rs:1673:58
     |
1673 |                 VariantData::Struct { fields, recovered: recovered.into() }
     |                                                          ^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `recovered`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: useless conversion to the same type: `rustc_ast::Recovered`
    --> compiler/rustc_parse/src/parser/item.rs:1685:54
     |
1685 |             VariantData::Struct { fields, recovered: recovered.into() }
     |                                                      ^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `recovered`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: useless conversion to the same type: `rustc_ast::Recovered`
    --> compiler/rustc_parse/src/parser/item.rs:1714:54
     |
1714 |             VariantData::Struct { fields, recovered: recovered.into() }
     |                                                      ^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `recovered`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: useless conversion to the same type: `rustc_ast::Recovered`
    --> compiler/rustc_parse/src/parser/item.rs:1721:54
     |
1721 |             VariantData::Struct { fields, recovered: recovered.into() }
     |                                                      ^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `recovered`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: `rustc_parse` (lib) generated 5 warnings (run `cargo clippy --fix --lib -p rustc_parse` to apply 5 suggestions)
    Checking rustc_ast_passes v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_ast_passes)
    Checking rustc_expand v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_expand)
    Checking rustc_builtin_macros v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_builtin_macros)
warning: useless conversion to the same type: `rustc_ast::BinOpKind`
    --> compiler/rustc_middle/src/ty/print/pretty.rs:1529:45
     |
1529 |                     AssocOp::from_ast_binop(binop.to_hir_binop().into()).precedence()
     |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `binop.to_hir_binop()`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
     = note: `-D clippy::useless-conversion` implied by `-D warnings`
     = help: to override `-D warnings` add `#[allow(clippy::useless_conversion)]`

warning: useless conversion to the same type: `mir::interpret::error::ErrorHandled`
   --> compiler/rustc_middle/src/ty/consts.rs:387:51
    |
387 |                     Err(err) => Err(Either::Right(err.into())),
    |                                                   ^^^^^^^^^^ help: consider removing `.into()`: `err`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: `rustc_middle` (lib) generated 2 warnings (run `cargo clippy --fix --lib -p rustc_middle` to apply 2 suggestions)
    Checking rustc_infer v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_infer)
    Checking rustc_mir_dataflow v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_mir_dataflow)
    Checking rustc_metadata v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_metadata)
    Checking rustc_pattern_analysis v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_pattern_analysis)
    Checking rustc_symbol_mangling v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_symbol_mangling)
    Checking rustc_incremental v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_incremental)
    Checking rustc_monomorphize v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_monomorphize)
    Checking rustc_ast_lowering v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_ast_lowering)
    Checking rustc_query_impl v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_query_impl)
    Checking rustc_smir v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_smir)
warning: useless conversion to the same type: `rustc_middle::ty::Const<'_>`
   --> compiler/rustc_symbol_mangling/src/v0.rs:385:25
    |
385 |                         ty::Const::from_bool(self.tcx, include_end).into(),
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `ty::Const::from_bool(self.tcx, include_end)`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
    = note: `-D clippy::useless-conversion` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::useless_conversion)]`

warning: `rustc_symbol_mangling` (lib) generated 1 warning (run `cargo clippy --fix --lib -p rustc_symbol_mangling` to apply 1 suggestion)
    Checking rustc_codegen_ssa v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_codegen_ssa)
    Checking rustc_resolve v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_resolve)
    Checking rustc_transmute v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_transmute)
    Checking rustc_trait_selection v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_trait_selection)
warning: useless conversion to the same type: `rustc_middle::ty::Term<'_>`
   --> compiler/rustc_trait_selection/src/traits/project.rs:409:28
    |
409 |             return Ok(Some(result.value.into()));
    |                            ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `result.value`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
    = note: `-D clippy::useless-conversion` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::useless_conversion)]`

warning: useless conversion to the same type: `rustc_middle::ty::Term<'_>`
   --> compiler/rustc_trait_selection/src/traits/project.rs:479:21
    |
479 |             Ok(Some(result.value.into()))
    |                     ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `result.value`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: `rustc_trait_selection` (lib) generated 2 warnings (run `cargo clippy --fix --lib -p rustc_trait_selection` to apply 2 suggestions)
    Checking rustc_lint v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_lint)
    Checking rustc_ty_utils v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_ty_utils)
    Checking rustc_const_eval v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_const_eval)
    Checking rustc_sanitizers v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_sanitizers)
    Checking rustc_hir_analysis v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_hir_analysis)
    Checking rustc_traits v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_traits)
    Checking rustc_borrowck v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_borrowck)
    Checking rustc_codegen_llvm v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_codegen_llvm)
    Checking rustc_privacy v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_privacy)
    Checking rustc_passes v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_passes)
warning: useless conversion to the same type: `interpret::place::MPlaceTy<'_>`
  --> compiler/rustc_const_eval/src/const_eval/eval_queries.rs:81:10
   |
81 |         &ret.clone().into(),
   |          ^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `ret.clone()`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
   = note: `-D clippy::useless-conversion` implied by `-D warnings`
   = help: to override `-D warnings` add `#[allow(clippy::useless_conversion)]`

warning: useless conversion to the same type: `interpret::place::MPlaceTy<'_, <M as interpret::machine::Machine<'_>>::Provenance>`
   --> compiler/rustc_const_eval/src/interpret/call.rs:857:14
    |
857 |             &ret.into(),
    |              ^^^^^^^^^^ help: consider removing `.into()`: `ret`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

    Checking rustc_mir_build v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_mir_build)
warning: `rustc_const_eval` (lib) generated 2 warnings (run `cargo clippy --fix --lib -p rustc_const_eval` to apply 2 suggestions)
warning: useless conversion to the same type: `usize`
    --> compiler/rustc_hir_analysis/src/check/wfcheck.rs:1604:32
     |
1604 |                     param_idx: idx.try_into().unwrap(),
     |                                ^^^^^^^^^^^^^^
     |
     = help: consider removing `.try_into()`
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
     = note: `-D clippy::useless-conversion` implied by `-D warnings`
     = help: to override `-D warnings` add `#[allow(clippy::useless_conversion)]`

warning: useless conversion to the same type: `usize`
    --> compiler/rustc_hir_analysis/src/check/wfcheck.rs:1613:70
     |
1613 |             Some(WellFormedLoc::Param { function: def_id, param_idx: idx.try_into().unwrap() }),
     |                                                                      ^^^^^^^^^^^^^^
     |
     = help: consider removing `.try_into()`
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

warning: `rustc_hir_analysis` (lib) generated 2 warnings
    Checking rustc_hir_typeck v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_hir_typeck)
    Checking rustc_mir_transform v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_mir_transform)
warning: useless conversion to the same type: `usize`
    --> compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs:2536:35
     |
2536 |                 idxs_matched.push(other_idx.into());
     |                                   ^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `other_idx`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
     = note: `-D clippy::useless-conversion` implied by `-D warnings`
     = help: to override `-D warnings` add `#[allow(clippy::useless_conversion)]`

warning: `rustc_hir_typeck` (lib) generated 1 warning (run `cargo clippy --fix --lib -p rustc_hir_typeck` to apply 1 suggestion)
    Checking rustc_interface v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_interface)
    Checking rustc_driver_impl v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_driver_impl)
    Checking rustc_driver v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc_driver)
    Checking rustc-main v0.0.0 (/home/matthias/vcs/github/rust/compiler/rustc)
    Finished `release` profile [optimized + debuginfo] target(s) in 1m 22s
Build completed successfully in 0:02:07

@matthiaskrgr
Copy link
Copy Markdown
Member

looks a bit like a mix of
clippy::useless_converison let x: A = A.into()
clippy::unneccessary_cast 1_u32 as u32
clippy::redundant_clone / unnecessary_to_owned let x: String= format!("a").to_string()

@rust-log-analyzer

This comment has been minimized.

@traviscross traviscross added the S-experimental Status: Ongoing experiment that does not require reviewing and won't be merged in its current state. label Aug 18, 2024
@estebank
Copy link
Copy Markdown
Contributor Author

@matthiaskrgr I'm trying to gauge how common the root cause of the recent time breakage (a stray identity .into()) is in the ecosystem. clippy::useless_conversion is the right analogue, but that one has the same issue that I partly side-stepped in this PR of being too eager and ignoring cfgs.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@estebank
Copy link
Copy Markdown
Contributor Author

estebank commented Jun 1, 2026

@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Jun 1, 2026
[Experimental] `<T as Into<T>>::into` lint
estebank added a commit to estebank/rust that referenced this pull request Jun 1, 2026
While working on rust-lang#129249, encountered these cases in the codebase of calling `.into()` unecessarily. Splitting them out so that they can land independently of the lint.
@rust-log-analyzer

This comment has been minimized.

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Jun 1, 2026

☀️ Try build successful (CI)
Build commit: 21cad1f (21cad1f647cfd05a566220f933edd88a53e50bcf, parent: c0bb140a37c81cf59a0b40c21c9413059644e294)

@estebank
Copy link
Copy Markdown
Contributor Author

estebank commented Jun 1, 2026

@craterbot check

@craterbot
Copy link
Copy Markdown
Collaborator

👌 Experiment pr-129249-1 created and queued.
🤖 Automatically detected try build 21cad1f
⚠️ Try build based on commit 6b3818c, but latest commit is cdb8d99. Did you forget to make a new try build?
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 1, 2026
jhpratt added a commit to jhpratt/rust that referenced this pull request Jun 3, 2026
…ochenkov

[tiny] remove unecessary `.into()` calls

While working on rust-lang#129249, encountered these cases in the codebase of calling `.into()` unecessarily. Splitting them out so that they can land independently of the lint.
@rustbot rustbot added the T-clippy Relevant to the Clippy team. label Jun 3, 2026
@rustbot

This comment has been minimized.

@estebank estebank changed the title [Experimental] <T as Into<T>>::into lint <T as Into<T>>::into lint Jun 3, 2026
@estebank
Copy link
Copy Markdown
Contributor Author

estebank commented Jun 3, 2026

This PR is rebased on top of #157218 for the cfg_select! changes. They are necessary for the lint to not trigger when using c_int and friends (because those it).

I am still waiting on the crater results, but I am satisfied with the current state of the patch. This is now ready for review.

As an update to #129249 (comment), these two open questions for t-lang:

  • we need to determine whether landing this in rustc and deprecate/make redundant clippy::useless_conversion is the best path forward (I believe it is)
  • Would you consider it a good idea to either add a second lint that is allow-by-default that doesn't have the filters, or allowing clippy::useless_conversion to pick those cases up, having more false positives but I believe no false negatives?

The impact of this pattern is significant enough that I feel like it deserves to be warn-by-default in rustc itself.

I also split the lint into two, one for the expected case and another for this occurring withing a macro expansion. I was under the initial plan of detecting whether the macro was local and only warning if that was the case, but even in local macros there are cases where calling .into() only incidentally sometimes is unnecessary (even encountered cases in our own codebase).

More complex scenarios (like glob imports or two step imports where intermediary steps are conditionally compiled) are not handled, but I only encountered 1 such case. We'll see how much that happens in the wild, but expect it to be low enough to be able to move forward.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

estebank added 6 commits June 4, 2026 16:14
When annotating an item with `#[cfg]` we track both the item that got annotated (with an inert attr) and the names of items that got directly cfg'd out. Extend this mechanism to also work for items within a `cfg_select!`.
Add two lints, very similar to `clippy::useless_conversion`, detecting
when `.into()` is being called unnecessarily. We present two separate
lints, one that triggers inside of macros, because it is common for
macros to have `.into()` calls to make the caller side easier to use. In
those cases people should still use the fully-qualified path instead,
but allow them to silence that lint without silencing the more general,
more likely to be problematic case.

This lint allows us to protect developers from the semver-hazard that
time 0.3.34 encountered, where a std change caused a valid method chain
to start producing inference errors. This is explicitly allowed by the
Rust project's backwards compatibility guarantees (inference is not
included in them), which means that relying on the blanket `impl Into`
is a problem.

The lint as implemented has false negatives: because of the way type
aliases are handled by the type system, we can't know whether
`let _: i32 = 0i32.into()` corresponds to a call on `i32` *or* a call on
a type alias that is `i32` only on some platforms (like `#[cfg(..)] type
Int = i32;`). To avoid false positives, we keep track of type aliases
that have been imported in the local crate and mark their types for
exclusion. This means that calling `let _: i32 = Int::into(0i32);` will
not be linted against even though it should.
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Jun 4, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.