You can ask the compiler:
fn foo(a1: [i32;3], a2:[i32;3]) -> _ {
a1.iter().chain(a2.iter())
}
Compiling playground v0.0.1 (/playground)
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> src/lib.rs:1:36
|
1 | fn foo(a1: [i32;3], a2:[i32;3]) -> _ {
| ^
| |
| not allowed in type signatures
| help: replace with the correct return type: `std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<i32>>`
error: aborting due to previous error
note the:
correct return type: `std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<i32>>`
Following this path will of course not directly lead to success in this case, as previous answers have explained, but it can get you to more insight:
Applying the replacement suggested by the compiler:
fn foo(a1: [i32;3], a2:[i32;3]) -> std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<i32>> {
a1.iter().chain(a2.iter())
}
gives
Compiling playground v0.0.1 (/playground)
error[E0106]: missing lifetime specifier
--> src/lib.rs:1:70
|
1 | fn foo(a1: [i32;3], a2:[i32;3]) -> std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<i32>> {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
help: consider using the `'static` lifetime
|
1 | fn foo(a1: [i32;3], a2:[i32;3]) -> std::iter::Chain<std::slice::Iter<'static, i32>, std::slice::Iter<i32>> {
| ^^^^^^^^
error[E0106]: missing lifetime specifier
--> src/lib.rs:1:93
|
1 | fn foo(a1: [i32;3], a2:[i32;3]) -> std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<i32>> {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
help: consider using the `'static` lifetime
|
1 | fn foo(a1: [i32;3], a2:[i32;3]) -> std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<'static, i32>> {
| ^^^^^^^^
error: aborting due to 2 previous errors
Then, adding the suggested 'static
lifetimes:
fn foo(a1: [i32;3], a2:[i32;3]) -> std::iter::Chain<std::slice::Iter<'static, i32>, std::slice::Iter<'static, i32>> {
a1.iter().chain(a2.iter())
}
finally explains the issue:
Compiling playground v0.0.1 (/playground)
error[E0515]: cannot return value referencing function parameter `a1`
--> src/lib.rs:2:5
|
2 | a1.iter().chain(a2.iter())
| --^^^^^^^^^^^^^^^^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| `a1` is borrowed here
error[E0515]: cannot return value referencing function parameter `a2`
--> src/lib.rs:2:5
|
2 | a1.iter().chain(a2.iter())
| ^^^^^^^^^^^^^^^^--^^^^^^^^
| | |
| | `a2` is borrowed here
| returns a value referencing data owned by the current function
error: aborting due to 2 previous errors
Once you realize that the iterators borrow their arguments, you can change the implementation of the function and re-try:
// now taking references as parameter, so that you don’t need to reference
// data owned by `foo` anymore
fn foo(a1: &[i32;3], a2: &[i32;3]) -> _ {
a1.iter().chain(a2.iter())
}
Compiling playground v0.0.1 (/playground)
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> src/lib.rs:1:39
|
1 | fn foo(a1: &[i32;3], a2: &[i32;3]) -> _ {
| ^
| |
| not allowed in type signatures
| help: replace with the correct return type: `std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<i32>>`
error: aborting due to previous error
Still suggesting std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<i32>>
:
fn foo(a1: &[i32;3], a2: &[i32;3]) -> std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<i32>> {
a1.iter().chain(a2.iter())
}
Compiling playground v0.0.1 (/playground)
error[E0106]: missing lifetime specifier
--> src/lib.rs:1:73
|
1 | fn foo(a1: &[i32;3], a2: &[i32;3]) -> std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<i32>> {
| -------- -------- ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a1` or `a2`
help: consider introducing a named lifetime parameter
|
1 | fn foo<'a>(a1: &'a [i32;3], a2: &'a [i32;3]) -> std::iter::Chain<std::slice::Iter<'a, i32>, std::slice::Iter<i32>> {
| ^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^^
error[E0106]: missing lifetime specifier
--> src/lib.rs:1:96
|
1 | fn foo(a1: &[i32;3], a2: &[i32;3]) -> std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<i32>> {
| -------- -------- ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a1` or `a2`
help: consider introducing a named lifetime parameter
|
1 | fn foo<'a>(a1: &'a [i32;3], a2: &'a [i32;3]) -> std::iter::Chain<std::slice::Iter<i32>, std::slice::Iter<'a, i32>> {
| ^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^^
error: aborting due to 2 previous errors
Okay, then this compiles:
fn foo<'a>(a1: &'a [i32;3], a2: &'a [i32;3]) -> std::iter::Chain<std::slice::Iter<'a, i32>, std::slice::Iter<'a, i32>> {
a1.iter().chain(a2.iter())
}