Skip to content

array_into_iter does not trigger for existing trait impl #88475

Closed

Description

@ehuss

I tried this code:

#![allow(unused)]

struct FooIter;

trait MyIntoIter {
    fn into_iter(self: Self) -> FooIter;
}

impl<T, const N: usize> MyIntoIter for [T; N] {
    fn into_iter(self: Self) -> FooIter {
        FooIter
    }
}

struct Point;

pub fn foo() {
    let points: [Point; 1] = [Point];
    let y = points.into_iter();
}

This code will not emit the array_into_iter lint. When updating to the 2021 edition, the code fails to compile:

error[E0034]: multiple applicable items in scope
  --> src/lib.rs:19:20
   |
19 |     let y = points.into_iter();
   |                    ^^^^^^^^^ multiple `into_iter` found
   |
note: candidate #1 is defined in an impl of the trait `MyIntoIter` for the type `[T; N]`
  --> src/lib.rs:10:5
   |
10 |     fn into_iter(self: Self) -> FooIter {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: candidate #2 is defined in an impl of the trait `IntoIterator` for the type `[T; N]`
help: disambiguate the associated function for candidate #1
   |
19 |     let y = MyIntoIter::into_iter(points);
   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: disambiguate the associated function for candidate #2
   |
19 |     let y = IntoIterator::into_iter(points);
   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I would expect the array_into_iter lint to give the appropriate suggestion.

Found in the 2021 crater run for:

Meta

rustc --version --verbose:

rustc 1.56.0-nightly (5eacec9ec 2021-08-28)
binary: rustc
commit-hash: 5eacec9ec7e112a0de1011519a57c45586d58414
commit-date: 2021-08-28
host: x86_64-apple-darwin
release: 1.56.0-nightly
LLVM version: 13.0.0

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    C-bugCategory: This is a bug.
    A-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`
    on Aug 30, 2021
  2. m-ou-se commented on Aug 30, 2021

    @m-ou-se
    Member

    The lint specifically checks if it is libcore's IntoIterator::into_iter before producing the lint:

    // Check if the method call actually calls the libcore
    // `IntoIterator::into_iter`.
    let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
    match cx.tcx.trait_of_item(def_id) {
    Some(trait_id) if cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_id) => {}
    _ => return,
    };

    Maybe the check shouldn't be there. Maybe it should only check if the receiver is an array.

  3. m-ou-se commented on Aug 30, 2021

    @m-ou-se
    Member

    Changing some of the checks to include this situation for that lint would result in a completely wrong diagnostic:

    warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
      --> src/main.rs:20:20
       |
    20 |     let y = points.into_iter();
       |                    ^^^^^^^^^
       |
    note: the lint level is defined here
      --> src/main.rs:1:9
       |
    1  | #![warn(array_into_iter)]
       |         ^^^^^^^^^^^^^^^
       = warning: this changes meaning in Rust 2021
       = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
    help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
       |
    20 |     let y = points.iter();
       |                    ~~~~
    help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
       |
    20 |     let y = IntoIterator::into_iter(points);
       |             ++++++++++++++++++++++++      ~
    

    Instead, it'd have to do something more like the prelude collision lint. It'd have to generate the right fully explicit call syntax and some message about it becoming ambiguous in the new edition.

  4. added a commit that references this issue on Aug 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-edition-2021Area: The 2021 editionA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions