This function

```
fn f() -> f64 {
0.0f64 + vec![1.0f64].into_iter().sum()
}
```

does not compile. The error is:

```
error: type annotations required: cannot resolve `<f64 as std::ops::Add<_>>::Output == f64` [E0284]
--> <anon>:2:4
|>
2 |> 0.0f64 + vec![1.0f64].into_iter().sum()
|>
```

Adding a type parameter to `sum`

solves the problem:

```
fn f() -> f64 {
0.0f64 + vec![1.0f64].into_iter().sum::<f64>()
}
```

Is this a bug or just a (bad) usability issue?

1 Like

I am not 100% sure; it certainly isn't great usability-wise, but I'm not sure if it's something that's fixible or not, other than an improved diagnostic.

The usability of sum() isn't very good, even tiny things stop the type inferencer:

```
fn total1(a: &[u32]) -> u32 { // OK
a.iter().sum()
}
fn total3(a: &[u32]) -> u32 { // Error
a.iter().sum() + 5u32
}
fn main() {}
```

```
use std::iter::Sum;
use std::ops::Add;
#[derive(Debug)]
struct Stack<T> {
data: Vec<T>,
sum: u64
}
impl<T> Stack<T> {
fn from_vec<'a>(vec: Vec<T>) -> Stack<T>
where T: 'a + Add<&'a T, Output=u64>,
u64: Sum<&'a T>
{
let sum = vec.iter().sum::<u64>();
Stack { data: vec, sum: sum }
}
}
fn main() {
let stack = Stack::from_vec(vec![1u32, 2, 3]);
println!("{:?}", stack);
}
```

I have a similar problem. I want to have a struct with a `Vec<T>`

field and a field of type u64 which stores the sum of the elements in `Vec<T>`

, I chose u64 to avoid overflow from summing T, however it seems I cannot have T types different from u64. What am I doing wrong?

Here's a link to playground Rust Playground

As far as I can tell, it's the `u64: Sum<&'a T>`

that restricts `T`

to `u64`

. Personally, I would write the `from_vec`

function like this:

```
fn from_vec<'a>(vec: Vec<T>) -> Stack<T>
where T: 'a + Into<u64> + Copy
{
let sum = vec.iter().map(|&v| v.into()).sum();
Stack { data: vec, sum: sum }
}
```

Instead of taking a `T`

that can somehow be summed to an `u64`

, just take a `T`

that can be converted to `u64`

and sum those.

Well, sure I can do that, but I thought `sum::<T>()`

was meant to sum into T and that some kind of similar solution was enabled behind the seens. Besides that, isn't Copy a performance penalty here (I'm not sure of `Into<T>`

)?

Well, in principle `sum::<T>()`

does sum into T, *as long as there exists a exist an impl of *`Sum<T>`

for the Item type of your iterator. The std library only provides impls of `Sum`

where T and the item type are identical.

The compiler will generate a version of `from_vec`

for each `T`

you call it with and optimize the function body for that specific type. The (implicit) `copy()`

and the `into()`

will be inlined and compiled to just what is needed to sum those numbers. (At least in a release build.)

In fact, the primitive numbers all implement `Copy`

and anytime you do any calculation you are implicitly using it. Without it, the Rust ownership model wouldn't even allow this:

```
let factor = 4.2;
let a = 33.0 * factor;
let b = 44.0 * factor;
```

Without `Copy`

, the factor would have been moved into the `33.0 * factor`

expression and not available in the second expression.

Thanks for clarification. I think it would be nice to have an impl of `Sum<T>`

for types where this is more or less straightforward...