]> git.lizzy.rs Git - rust.git/commitdiff
Add filter to detect local crates for rustc_on_unimplemented
authorEsteban Küber <esteban@kuber.com.ar>
Sat, 20 Jan 2018 09:33:39 +0000 (01:33 -0800)
committerEsteban Küber <esteban@kuber.com.ar>
Thu, 1 Feb 2018 23:06:21 +0000 (15:06 -0800)
16 files changed:
src/libcore/fmt/mod.rs
src/libcore/iter/iterator.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/on_unimplemented.rs
src/test/ui/impl-trait/equality.rs
src/test/ui/lint/use_suggestion_json.stderr
src/test/ui/mismatched_types/binops.rs
src/test/ui/mismatched_types/binops.stderr
src/test/ui/on-unimplemented/auxiliary/no_debug.rs [new file with mode: 0644]
src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr
src/test/ui/on-unimplemented/no-debug.rs [new file with mode: 0644]
src/test/ui/on-unimplemented/no-debug.stderr [new file with mode: 0644]
src/test/ui/span/multiline-span-simple.rs
src/test/ui/span/multiline-span-simple.stderr
src/test/ui/suggestions/iterate-str.rs [new file with mode: 0644]
src/test/ui/suggestions/iterate-str.stderr [new file with mode: 0644]

index 6c8a1c3062b00633619ba56a7c7296ce8119d19d..8ad5a9861a02f07c586f3b9457d3f6f988f71c45 100644 (file)
@@ -530,9 +530,12 @@ fn fmt(&self, fmt: &mut Formatter) -> Result {
 /// }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \
-                            defined in your crate, add `#[derive(Debug)]` or \
-                            manually implement it"]
+#[rustc_on_unimplemented(
+    on(crate_local, label="`{Self}` cannot be formatted using `:?`; \
+                            add `#[derive(Debug)]` or manually implement `{Debug}`"),
+    message="`{Self}` doesn't implement `{Debug}`",
+    label="`{Self}` cannot be formatted using `:?` because it doesn't implement `{Debug}`",
+)]
 #[lang = "debug_trait"]
 pub trait Debug {
     /// Formats the value using the given formatter.
@@ -593,9 +596,11 @@ pub trait Debug {
 ///
 /// println!("The origin is: {}", origin);
 /// ```
-#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default \
-                            formatter; try using `:?` instead if you are using \
-                            a format string"]
+#[rustc_on_unimplemented(
+    message="`{Self}` doesn't implement `{Display}`",
+    label="`{Self}` cannot be formatted with the default formatter; \
+           try using `:?` instead if you are using a format string",
+)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Display {
     /// Formats the value using the given formatter.
index 35cd7441c66bcf4e0ef93706c54d4ada83a6b365..296fb8733ba6c858068f7675d1c2ed3fe9709804 100644 (file)
@@ -28,8 +28,13 @@ fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
 /// [module-level documentation]: index.html
 /// [impl]: index.html#implementing-iterator
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \
-                            `.iter()` or a similar method"]
+#[rustc_on_unimplemented(
+    on(
+        _Self="&str",
+        label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
+    ),
+    label="`{Self}` is not an iterator; maybe try calling `.iter()` or a similar method"
+)]
 #[doc(spotlight)]
 pub trait Iterator {
     /// The type of the elements being iterated over.
index f5ff122668558895ab35340d967ce1e6aa63c2a2..be7ecbce8af7395ad045ae666a44bde48d931f40 100644 (file)
@@ -384,6 +384,10 @@ fn on_unimplemented_note(
                         Some(ty_str.clone())));
         }
 
+        if let Some(true) = self_ty.ty_to_def_id().map(|def_id| def_id.is_local()) {
+            flags.push(("crate_local".to_string(), None));
+        }
+
         if let Ok(Some(command)) = OnUnimplementedDirective::of_item(
             self.tcx, trait_ref.def_id, def_id
         ) {
index a493b7f0bb60347cc9acc979fc0a8a305f0c5a3f..8c2c1cfa454729c5cbfcf1593dde5771617b4efa 100644 (file)
@@ -185,8 +185,7 @@ pub fn evaluate(&self,
         let mut message = None;
         let mut label = None;
         let mut note = None;
-        info!("evaluate({:?}, trait_ref={:?}, options={:?})",
-              self, trait_ref, options);
+        info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options);
 
         for command in self.subcommands.iter().chain(Some(self)).rev() {
             if let Some(ref condition) = command.condition {
index 36df4f0eb4d46f7cc25792807680fa6c622dd3cc..9d9d4cef3119a11c50fb4e59879bf3eb3b94a7c7 100644 (file)
@@ -32,7 +32,7 @@ fn sum_to(n: u32) -> impl Foo {
         0
     } else {
         n + sum_to(n - 1)
-        //~^ ERROR the trait bound `u32: std::ops::Add<impl Foo>` is not satisfied
+        //~^ ERROR cannot add `impl Foo` to `u32`
     }
 }
 
index abbf3da513a6faf6272002919d26057e50d9aefd..86c2ad4c0e7a4fabae55f6a97447fb4de39b0d56 100644 (file)
@@ -2,7 +2,72 @@
   "message": "cannot find type `Iter` in this scope",
   "code": {
     "code": "E0412",
-    "explanation": null
+    "explanation": "
+The type name used is not in scope.
+
+Erroneous code examples:
+
+```compile_fail,E0412
+impl Something {} // error: type name `Something` is not in scope
+
+// or:
+
+trait Foo {
+    fn bar(N); // error: type name `N` is not in scope
+}
+
+// or:
+
+fn foo(x: T) {} // type name `T` is not in scope
+```
+
+To fix this error, please verify you didn't misspell the type name, you did
+declare it or imported it into the scope. Examples:
+
+```
+struct Something;
+
+impl Something {} // ok!
+
+// or:
+
+trait Foo {
+    type N;
+
+    fn bar(_: Self::N); // ok!
+}
+
+// or:
+
+fn foo<T>(x: T) {} // ok!
+```
+
+Another case that causes this error is when a type is imported into a parent
+module. To fix this, you can follow the suggestion and use File directly or
+`use super::File;` which will import the types from the parent namespace. An
+example that causes this error is below:
+
+```compile_fail,E0412
+use std::fs::File;
+
+mod foo {
+    fn some_function(f: File) {}
+}
+```
+
+```
+use std::fs::File;
+
+mod foo {
+    // either
+    use super::File;
+    // or
+    // use std::fs::File;
+    fn foo(f: File) {}
+}
+# fn main() {} // don't insert it for us; that'll break imports
+```
+"
   },
   "level": "error",
   "spans": [
index e45616cd67a811419117cc16d6152700e250f66f..5144b59955cc9da6ef33a697fa9921df3de7470f 100644 (file)
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 fn main() {
-    1 + Some(1); //~ ERROR is not satisfied
-    2 as usize - Some(1); //~ ERROR is not satisfied
-    3 * (); //~ ERROR is not satisfied
-    4 / ""; //~ ERROR is not satisfied
+    1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}`
+    2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
+    3 * (); //~ ERROR cannot multiply `()` to `{integer}`
+    4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
     5 < String::new(); //~ ERROR is not satisfied
     6 == Ok(1); //~ ERROR is not satisfied
 }
index 57e66794a58a96d7d575542fcbc703598251d551..1b7fba050636f94e30891fb7f0916037ec214834 100644 (file)
@@ -1,7 +1,7 @@
 error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}`
   --> $DIR/binops.rs:12:7
    |
-12 |     1 + Some(1); //~ ERROR is not satisfied
+12 |     1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}`
    |       ^ no implementation for `{integer} + std::option::Option<{integer}>`
    |
    = help: the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`
@@ -9,7 +9,7 @@ error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}`
 error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize`
   --> $DIR/binops.rs:13:16
    |
-13 |     2 as usize - Some(1); //~ ERROR is not satisfied
+13 |     2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
    |                ^ no implementation for `usize - std::option::Option<{integer}>`
    |
    = help: the trait `std::ops::Sub<std::option::Option<{integer}>>` is not implemented for `usize`
@@ -17,7 +17,7 @@ error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize`
 error[E0277]: cannot multiply `()` to `{integer}`
   --> $DIR/binops.rs:14:7
    |
-14 |     3 * (); //~ ERROR is not satisfied
+14 |     3 * (); //~ ERROR cannot multiply `()` to `{integer}`
    |       ^ no implementation for `{integer} * ()`
    |
    = help: the trait `std::ops::Mul<()>` is not implemented for `{integer}`
@@ -25,7 +25,7 @@ error[E0277]: cannot multiply `()` to `{integer}`
 error[E0277]: cannot divide `{integer}` by `&str`
   --> $DIR/binops.rs:15:7
    |
-15 |     4 / ""; //~ ERROR is not satisfied
+15 |     4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
    |       ^ no implementation for `{integer} / &str`
    |
    = help: the trait `std::ops::Div<&str>` is not implemented for `{integer}`
diff --git a/src/test/ui/on-unimplemented/auxiliary/no_debug.rs b/src/test/ui/on-unimplemented/auxiliary/no_debug.rs
new file mode 100644 (file)
index 0000000..0f833c6
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+// ignore-tidy-linelength
+
+#![crate_type = "lib"]
+
+pub struct Bar;
index 2ea9b67f260254401a9301ba393571b7fcf33f6e..c4bac12eebdbe70376607c68b58a79b99e300ccc 100644 (file)
-error[E0277]: trait message `[i32]`
-  --> $DIR/multiple-impls-complex-filtering.rs:46:5
+error[E0277]: trait message
+  --> $DIR/multiple-impls-complex-filtering.rs:49:5
    |
-46 |     Index::index(&[] as &[i32], 2usize);
-   |     ^^^^^^^^^^^^ u32 message
+49 |     Index::index(&[] as &[i32], 2usize);
+   |     ^^^^^^^^^^^^ trait label if i32
    |
-   = help: the trait `Index<_>` is not implemented for `[i32]`
+   = help: the trait `Index<usize>` is not implemented for `[i32]`
 note: required by `Index::index`
-  --> $DIR/multiple-impls-complex-filtering.rs:25:5
+  --> $DIR/multiple-impls-complex-filtering.rs:26:5
    |
-25 |     fn index(&self, index: Idx) -> &Self::Output;
+26 |     fn index(&self, index: Idx) -> &Self::Output;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: trait message `[i32]`
-  --> $DIR/multiple-impls-complex-filtering.rs:46:5
+error[E0277]: trait message
+  --> $DIR/multiple-impls-complex-filtering.rs:49:5
    |
-46 |     Index::index(&[] as &[i32], 2usize);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u32 message
+49 |     Index::index(&[] as &[i32], 2usize);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label if i32
    |
-   = help: the trait `Index<_>` is not implemented for `[i32]`
+   = help: the trait `Index<usize>` is not implemented for `[i32]`
 
-error[E0277]: trait message `[i32]`
-  --> $DIR/multiple-impls-complex-filtering.rs:47:5
+error[E0277]: trait message
+  --> $DIR/multiple-impls-complex-filtering.rs:50:5
    |
-47 |     Index::index(&[] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^ u32 message
+50 |     Index::index(&[] as &[i32], 2u32);
+   |     ^^^^^^^^^^^^ trait label if i32
    |
-   = help: the trait `Index<_>` is not implemented for `[i32]`
+   = help: the trait `Index<u32>` is not implemented for `[i32]`
 note: required by `Index::index`
-  --> $DIR/multiple-impls-complex-filtering.rs:25:5
+  --> $DIR/multiple-impls-complex-filtering.rs:26:5
    |
-25 |     fn index(&self, index: Idx) -> &Self::Output;
+26 |     fn index(&self, index: Idx) -> &Self::Output;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: trait message `[i32]`
-  --> $DIR/multiple-impls-complex-filtering.rs:47:5
+error[E0277]: trait message
+  --> $DIR/multiple-impls-complex-filtering.rs:50:5
    |
-47 |     Index::index(&[] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u32 message
+50 |     Index::index(&[] as &[i32], 2u32);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label if i32
    |
-   = help: the trait `Index<_>` is not implemented for `[i32]`
+   = help: the trait `Index<u32>` is not implemented for `[i32]`
 
-error: aborting due to 4 previous errors
+error[E0277]: trait message
+  --> $DIR/multiple-impls-complex-filtering.rs:51:5
+   |
+51 |     Index::index(&[] as &[u32], 2u32);
+   |     ^^^^^^^^^^^^ trait label
+   |
+   = help: the trait `Index<_>` is not implemented for `[u32]`
+note: required by `Index::index`
+  --> $DIR/multiple-impls-complex-filtering.rs:26:5
+   |
+26 |     fn index(&self, index: Idx) -> &Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: trait message
+  --> $DIR/multiple-impls-complex-filtering.rs:51:5
+   |
+51 |     Index::index(&[] as &[u32], 2u32);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label
+   |
+   = help: the trait `Index<_>` is not implemented for `[u32]`
+
+error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
+  --> $DIR/multiple-impls-complex-filtering.rs:55:5
+   |
+55 |     Index::index(&[] as &[i32], Foo(2u32));
+   |     ^^^^^^^^^^^^ impl foo [i32] Foo<u32> Index
+   |
+   = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
+note: required by `Index::index`
+  --> $DIR/multiple-impls-complex-filtering.rs:26:5
+   |
+26 |     fn index(&self, index: Idx) -> &Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
+  --> $DIR/multiple-impls-complex-filtering.rs:55:5
+   |
+55 |     Index::index(&[] as &[i32], Foo(2u32));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl foo [i32] Foo<u32> Index
+   |
+   = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
+
+error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
+  --> $DIR/multiple-impls-complex-filtering.rs:58:5
+   |
+58 |     Index::index(&[] as &[i32], Bar(2u32));
+   |     ^^^^^^^^^^^^ on impl for Bar
+   |
+   = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
+note: required by `Index::index`
+  --> $DIR/multiple-impls-complex-filtering.rs:26:5
+   |
+26 |     fn index(&self, index: Idx) -> &Self::Output;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
+  --> $DIR/multiple-impls-complex-filtering.rs:58:5
+   |
+58 |     Index::index(&[] as &[i32], Bar(2u32));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar
+   |
+   = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
+
+error: aborting due to 10 previous errors
 
diff --git a/src/test/ui/on-unimplemented/no-debug.rs b/src/test/ui/on-unimplemented/no-debug.rs
new file mode 100644 (file)
index 0000000..fff6122
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:no_debug.rs
+
+extern crate no_debug;
+
+use no_debug::Bar;
+
+struct Foo;
+
+fn main() {
+    println!("{:?} {:?}", Foo, Bar);
+    println!("{} {}", Foo, Bar);
+}
+//~^^^ ERROR `Foo` doesn't implement `std::fmt::Debug`
+//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Debug`
+//~^^^^ ERROR `Foo` doesn't implement `std::fmt::Display`
+//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Display`
+
diff --git a/src/test/ui/on-unimplemented/no-debug.stderr b/src/test/ui/on-unimplemented/no-debug.stderr
new file mode 100644 (file)
index 0000000..af5b1e9
--- /dev/null
@@ -0,0 +1,38 @@
+error[E0277]: `Foo` doesn't implement `std::fmt::Debug`
+  --> $DIR/no-debug.rs:20:27
+   |
+20 |     println!("{:?} {:?}", Foo, Bar);
+   |                           ^^^ `Foo` cannot be formatted using `:?`; add `#[derive(Debug)]` or manually implement `std::fmt::Debug`
+   |
+   = help: the trait `std::fmt::Debug` is not implemented for `Foo`
+   = note: required by `std::fmt::Debug::fmt`
+
+error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Debug`
+  --> $DIR/no-debug.rs:20:32
+   |
+20 |     println!("{:?} {:?}", Foo, Bar);
+   |                                ^^^ `no_debug::Bar` cannot be formatted using `:?` because it doesn't implement `std::fmt::Debug`
+   |
+   = help: the trait `std::fmt::Debug` is not implemented for `no_debug::Bar`
+   = note: required by `std::fmt::Debug::fmt`
+
+error[E0277]: `Foo` doesn't implement `std::fmt::Display`
+  --> $DIR/no-debug.rs:21:23
+   |
+21 |     println!("{} {}", Foo, Bar);
+   |                       ^^^ `Foo` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `Foo`
+   = note: required by `std::fmt::Display::fmt`
+
+error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Display`
+  --> $DIR/no-debug.rs:21:28
+   |
+21 |     println!("{} {}", Foo, Bar);
+   |                            ^^^ `no_debug::Bar` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `no_debug::Bar`
+   = note: required by `std::fmt::Display::fmt`
+
+error: aborting due to 4 previous errors
+
index f8e4cbcbf191f3a838bb5523b2f1cabe609d7d5f..dd09534480e10dde5247fedd7058cd6bd6ffb8d9 100644 (file)
@@ -20,7 +20,7 @@ fn main() {
     let x = 1;
     let y = 2;
     let z = 3;
-    foo(1 as u32 + //~ ERROR not satisfied
+    foo(1 as u32 + //~ ERROR cannot add `()` to `u32`
 
         bar(x,
 
index b6182825fc27808e2a7739366dbbc7c024381c91..a18dfeb31d9ef0bb86d4a2705bc19686a316d357 100644 (file)
@@ -1,7 +1,7 @@
 error[E0277]: cannot add `()` to `u32`
   --> $DIR/multiline-span-simple.rs:23:18
    |
-23 |     foo(1 as u32 + //~ ERROR not satisfied
+23 |     foo(1 as u32 + //~ ERROR cannot add `()` to `u32`
    |                  ^ no implementation for `u32 + ()`
    |
    = help: the trait `std::ops::Add<()>` is not implemented for `u32`
diff --git a/src/test/ui/suggestions/iterate-str.rs b/src/test/ui/suggestions/iterate-str.rs
new file mode 100644 (file)
index 0000000..1022491
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    for c in "foobarbaz" {
+        println!("{}", c);
+    }
+    //~^^^ ERROR the trait bound `&str: std::iter::Iterator` is not satisfied
+    //~| NOTE `&str` is not an iterator; try calling `.chars()` or `.bytes()`
+    //~| HELP the trait `std::iter::Iterator` is not implemented for `&str`
+    //~| NOTE required by `std::iter::IntoIterator::into_iter`
+}
diff --git a/src/test/ui/suggestions/iterate-str.stderr b/src/test/ui/suggestions/iterate-str.stderr
new file mode 100644 (file)
index 0000000..59da6d7
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied
+  --> $DIR/iterate-str.rs:12:5
+   |
+12 | /     for c in "foobarbaz" {
+13 | |         println!("{}", c);
+14 | |     }
+   | |_____^ `&str` is not an iterator; try calling `.chars()` or `.bytes()`
+   |
+   = help: the trait `std::iter::Iterator` is not implemented for `&str`
+   = note: required by `std::iter::IntoIterator::into_iter`
+
+error: aborting due to previous error
+