Vec of objects implementing generic trait [duplicate] - rust

This question already has answers here:
How can I have a collection of objects that differ by their associated type?
(3 answers)
Vector of objects belonging to a trait
(3 answers)
Closed 4 years ago.
I am building a command-line application. I have the following trait:
trait ValidatedCommand {
type Output;
fn run() -> Result<Self::Output, std::io::Error>;
}
and I have the following two implementations for it:
struct First;
impl ValidatedCommand for First {
type Output = i32;
fn run() -> Result<i32, std::io::Error> {
Ok(1)
}
}
impl First {
fn new() -> First {
First {}
}
}
struct Second;
impl ValidatedCommand for Second {
type Output = String;
fn run() -> Result<String, std::io::Error> {
Ok(String::from("hello"))
}
}
impl Second {
fn new() -> Second {
Second {}
}
}
Both structs implement the trait, one returning a String and the other an i32.
I'm trying to create a Vec of that trait, but I'm not sure how to go about it. I tried the following:
fn main() {
let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
playground.
which errors with
error[E0191]: the value of the associated type `Output` (from the trait `ValidatedCommand`) must be specified
--> src/main.rs:33:23
|
2 | type Output;
| ------------ `Output` defined here
...
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^ associated type `Output` must be specified
error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
--> src/main.rs:33:19
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `std::vec::Vec`
error[E0038]: the trait `ValidatedCommand` cannot be made into an object
--> src/main.rs:33:19
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ValidatedCommand` cannot be made into an object
|
= note: method `run` has no receiver
error[E0308]: mismatched types
--> src/main.rs:33:52
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^ expected trait ValidatedCommand, found struct `First`
|
= note: expected type `dyn ValidatedCommand`
found type `First`
error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
--> src/main.rs:33:47
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `std::slice::<impl [T]>::into_vec`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
--> src/main.rs:33:47
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: slice and array elements must have `Sized` type
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error[E0038]: the trait `ValidatedCommand` cannot be made into an object
--> src/main.rs:33:47
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ValidatedCommand` cannot be made into an object
|
= note: method `run` has no receiver
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
--> src/main.rs:33:47
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `std::vec::Vec`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error[E0038]: the trait `ValidatedCommand` cannot be made into an object
--> src/main.rs:33:47
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ValidatedCommand` cannot be made into an object
|
= note: method `run` has no receiver
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
I am thinking that maybe there is a way to make use of the associated type, but I have no idea how I might go about it.
Is there a way to get this vector creation to compile?

Related

Error compiling dependency to a proc-macro when targeting wasm

I have a procedural macro I have implemented which depends on the proc-macro-error crate. My client project depends on this macro crate.
When I build for native, everything works perfectly, but when I build for wasm, I get a number of errors thrown from proc-macro-error:
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:33:38
|
33 | let span = span_range.collapse().unwrap();
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:49:53
|
49 | res.span_note(span_range.collapse().unwrap(), msg)
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:52:53
|
52 | res.span_help(span_range.collapse().unwrap(), msg)
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:60:42
|
60 | let span = span_range.collapse().unwrap();
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0277]: the trait bound `proc_macro::TokenStream: From<TokenStream2>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:459:29
|
459 | gen_error().into()
| ^^^^ the trait `From<TokenStream2>` is not implemented for `proc_macro::TokenStream`
|
= help: the trait `From<proc_macro::TokenTree>` is implemented for `proc_macro::TokenStream`
= note: required because of the requirements on the impl of `Into<proc_macro::TokenStream>` for `TokenStream2`
error[E0277]: the trait bound `proc_macro::TokenStream: From<TokenStream2>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:464:34
|
464 | Ok(_) => gen_error().into(),
| ^^^^ the trait `From<TokenStream2>` is not implemented for `proc_macro::TokenStream`
|
= help: the trait `From<proc_macro::TokenTree>` is implemented for `proc_macro::TokenStream`
= note: required because of the requirements on the impl of `Into<proc_macro::TokenStream>` for `TokenStream2`
error[E0277]: the trait bound `proc_macro2::Span: From<proc_macro::Span>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:549:37
|
549 | first: self.clone().into(),
| ^^^^ the trait `From<proc_macro::Span>` is not implemented for `proc_macro2::Span`
|
= note: required because of the requirements on the impl of `Into<proc_macro2::Span>` for `proc_macro::Span`
error[E0277]: the trait bound `proc_macro2::Span: From<proc_macro::Span>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:550:36
|
550 | last: self.clone().into(),
| ^^^^ the trait `From<proc_macro::Span>` is not implemented for `proc_macro2::Span`
|
= note: required because of the requirements on the impl of `Into<proc_macro2::Span>` for `proc_macro::Span`
It doesn't make sense to me why there should be an issue: this code is not actually compiled for wasm, it's only called inside the proc macro, which is used at compile time.
How can I solve this issue?

error: the method `set_bit` exists for type `u8`, but its trait bounds were not satisfied (works for usize?)

I'm working on some bit manipulation code that converts primitive integers into a newtype called struct Bits(Vec<bool>) where the bools in the vec each represent a single bit. I implemented the From trait to convert from Bits back to usize and it worked perfectly. I changed the same implementation of From to convert from Bits back to u8 and it complains about u8 not satisfying my trait bounds for things like BitAnd even though u8 definitely does have an implementation for BitAnd. In fact, u8 and usize implement BitAnd via the exact same call to a macro in Rust's library. The trait bounds in question are from a blanket implementation from my BitMan trait. What am I not understanding that makes the usize work fine but the u8 not even compile?
The full error and notes I get is:
error[E0599]: the method `set_bit` exists for type `u8`, but its trait bounds were not satisfied
--> src\lib.rs:131:24
|
131 | new_u8.set_bit(index, Bit(current_bit)).unwrap();
| ^^^^^^^ method cannot be called on `u8` due to unsatisfied trait bounds
note: trait bound `&mut u8: BitAnd` was not satisfied
--> src\lib.rs:168:8
|
166 | impl<T> BitMan for T
| ------ -
167 | where
168 | T: BitAnd<Output = Self>
| ^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here
note: the following trait bounds were not satisfied:
`<&mut u8 as BitAnd>::Output = &mut u8`
`<&u8 as BitAnd>::Output = &u8`
--> src\lib.rs:168:15
|
166 | impl<T> BitMan for T
| ------ -
167 | where
168 | T: BitAnd<Output = Self>
| ^^^^^^^^^^^^^ unsatisfied trait bound introduced here
note: trait bound `&mut u8: BitOr` was not satisfied
--> src\lib.rs:169:11
|
166 | impl<T> BitMan for T
| ------ -
...
169 | + BitOr<Output = Self>
| ^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here
note: the following trait bounds were not satisfied:
`<&mut u8 as BitOr>::Output = &mut u8`
`<&u8 as BitOr>::Output = &u8`
--> src\lib.rs:169:17
|
166 | impl<T> BitMan for T
| ------ -
...
169 | + BitOr<Output = Self>
| ^^^^^^^^^^^^^ unsatisfied trait bound introduced here
note: trait bound `&mut u8: Not` was not satisfied
--> src\lib.rs:170:11
|
166 | impl<T> BitMan for T
| ------ -
...
170 | + Not<Output = Self>
| ^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here
note: the following trait bounds were not satisfied:
`<&mut u8 as Not>::Output = &mut u8`
`<&u8 as Not>::Output = &u8`
--> src\lib.rs:170:15
|
166 | impl<T> BitMan for T
| ------ -
...
170 | + Not<Output = Self>
| ^^^^^^^^^^^^^ unsatisfied trait bound introduced here
note: trait bound `&mut u8: Shl` was not satisfied
--> src\lib.rs:171:11
|
166 | impl<T> BitMan for T
| ------ -
...
171 | + Shl<Output = Self>
| ^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here
note: the following trait bounds were not satisfied:
`<&mut u8 as Shl>::Output = &mut u8`
`<&u8 as Shl>::Output = &u8`
--> src\lib.rs:171:15
|
166 | impl<T> BitMan for T
| ------ -
...
171 | + Shl<Output = Self>
| ^^^^^^^^^^^^^ unsatisfied trait bound introduced here
note: the following trait bounds were not satisfied:
`&mut u8: num::Zero`
`&u8: num::Zero`
--> src\lib.rs:173:11
|
166 | impl<T> BitMan for T
| ------ -
...
173 | + Zero
| ^^^^ unsatisfied trait bound introduced here
note: the following trait bounds were not satisfied:
`&mut u8: One`
`&u8: One`
--> src\lib.rs:174:11
|
166 | impl<T> BitMan for T
| ------ -
...
174 | + One
| ^^^ unsatisfied trait bound introduced here
note: the following trait bounds were not satisfied:
`&mut u8: From<usize>`
`&u8: From<usize>`
`u8: From<usize>`
--> src\lib.rs:175:11
|
166 | impl<T> BitMan for T
| ------ -
...
175 | + From<usize>
| ^^^^^^^^^^^ unsatisfied trait bound introduced here
note: trait bound `&mut u8: Clone` was not satisfied
--> src\lib.rs:176:11
|
166 | impl<T> BitMan for T
| ------ -
...
176 | + Clone
| ^^^^^ unsatisfied trait bound introduced here
_
pub struct Bits(Vec<bool>);
impl<T> BitMan for T
where
T: BitAnd<Output = Self>
+ BitOr<Output = Self>
+ Not<Output = Self>
+ Shl<Output = Self>
+ Sized
+ Zero
+ One
+ From<usize>
+ Clone
+ PartialEq,
{
fn set_bit(mut self, index: usize, bit: Bit) -> Result<Bit, BitManError> {
if index > size_of::<Self>() {
return Err(BitManError::OutOfBounds(format!(
"Index {:?} is larger than total size {:?}.",
index,
size_of::<Self>()
)));
}
if bit.0 {
let mask: Self = Self::one();
let mask: Self = mask << (size_of::<Self>() - index).into();
self = self & !mask.clone();
return Ok(Bit(self & mask != Self::zero()));
} else {
let mask: Self = Self::one();
let mask: Self = mask << (size_of::<Self>() - index).into();
self = self | mask.clone();
return Ok(Bit(self & mask != Self::zero()));
}
}
}
impl From<Bits> for usize {
fn from(bits_to_convert: Bits) -> Self {
if bits_to_convert.0.len() > size_of::<usize>() {
let shortened_bits: Bits = Bits(
bits_to_convert.0
[(bits_to_convert.0.len() - size_of::<usize>())..bits_to_convert.0.len()]
.to_vec(),
);
usize::from(shortened_bits)
} else {
let mut new_usize: usize = Default::default();
for (index, current_bit) in bits_to_convert.0.clone().into_iter().enumerate() {
new_usize.set_bit(index, Bit(current_bit)).unwrap();
}
if bits_to_convert.0.len() < size_of::<usize>() {
new_usize = new_usize >> size_of::<usize>() - bits_to_convert.0.len();
}
new_usize
}
}
}
impl From<Bits> for u8 {
fn from(bits_to_convert: Bits) -> Self {
if bits_to_convert.0.len() > size_of::<u8>() {
let shortened_bits: Bits = Bits(
bits_to_convert.0
[(bits_to_convert.0.len() - size_of::<u8>())..bits_to_convert.0.len()]
.to_vec(),
);
u8::from(shortened_bits)
} else {
let mut new_u8: u8 = Default::default();
for (index, current_bit) in bits_to_convert.0.clone().into_iter().enumerate() {
new_u8.set_bit(index, Bit(current_bit)).unwrap();
}
if bits_to_convert.0.len() < size_of::<u8>() {
new_u8 = new_u8 >> size_of::<u8>() - bits_to_convert.0.len();
}
new_u8
}
}
}
The error is quite sizeable but I'll pick out one particular problematic portion and highlight it:
note: the following trait bounds were not satisfied:
`&mut u8: From<usize>`
`&u8: From<usize>`
`u8: From<usize>`
--> src\lib.rs:175:11
|
166 | impl<T> BitMan for T
| ------ -
...
175 | + From<usize>
| ^^^^^^^^^^^ unsatisfied trait bound introduced here
When the compiler sees new_u8.set_bit(...), it will try u8, &u8, and &mut u8 to try to match a trait implementation. But as you can see above, none of these types implement From<usize>. You can see this better if you call the trait method explicitly for the implementation you expect using the fully qualified syntax:
<u8 as BitMan>::set_bit(new_u8, ...)
error[E0277]: the trait bound `u8: From<usize>` is not satisfied
--> src/lib.rs:87:17
|
87 | <u8 as BitMan>::set_bit(new_u8, index, Bit(current_bit)).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<usize>` is not implemented for `u8`
|
= help: the following implementations were found:
<u8 as From<Bits>>
<u8 as From<NonZeroU8>>
<u8 as From<bool>>
<f32 as From<i16>>
and 73 others
Based on your wording, I'm guessing you're assuming it'd be implemented for u8, however usize can represent way more values than can fit in a u8, such conversion would be lossy. The TryFrom trait is used for conversions that can fail. Regardless, you should probably use T: Shl<usize, Output = Self> instead and drop the .into()s and From constraint. This compiles.
You should probably also change it to change self by mutable reference. Because you're passing self by value, right now it'd simply copy the usize/u8, modify it within the function, and then do nothing with it; it won't modify the original value.

Unable to mock a trait returning Option<&String>

I am trying to mock a trait using the mockall crate:
#[automock]
trait Foo {
fn foo(input: &Vec<String>) -> Option<&String>;
}
However, I get the following error:
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> src/names_matcher.rs:79:51
|
79 | fn foo(input: &Vec<String>) -> Option<&String>;
| ^ explicit lifetime name needed here
error[E0623]: lifetime mismatch
--> src/names_matcher.rs:77:9
|
77 | #[automock]
| ^^^^^^^^^^^
| |
| ...but data from `input` is returned here
78 | trait Foo {
79 | fn foo(input: &Vec<String>) -> Option<&String>;
| ------------ this parameter and the return type are declared with different lifetimes...
The function I want to implement will return either None or Some with a reference to one of the elements of the vector in input. If I try to define the lifetimes taking this into account:
#[automock]
trait Foo {
fn foo<'r>(input: &'r Vec<String>) -> Option<&'r String>;
}
I get the following:
error[E0261]: use of undeclared lifetime name `'r`
--> src/names_matcher.rs:79:20
|
79 | fn foo<'r>(input: &'r Vec<String>) -> Option<&'r String>;
| ^^ undeclared lifetime
|
help: consider introducing lifetime `'r` here
|
77 | #[automock]<'r>
| ^^^^
help: consider introducing lifetime `'r` here
|
77 | 'r, #[automock]
| ^^^
But none of the suggestions work, they produce syntax errors. Is there a way to mock a trait like the one I defined above?

Reference traits: no implementation for `&T * &T`

I try to write generic method and specify some type T: num_traits::float::Float from num-traits crate. How should I ask &T to implement basic numeric methods such as multiplication?
use splines::{Interpolation, Key, Spline, interpolate};
use num_traits::{float::Float, identities};
use conv::prelude::*;
struct Interpolator<T>
where T: Float + interpolate::One + interpolate::Trigo {
target_x: Vec<T>,
}
impl<T> Interpolator<T>
where T: Float + interpolate::One + interpolate::Trigo {
fn interpolate<U>(&self, x: &[T], y: &[U]) -> Vec<U>
where U: Float + identities::Zero {
assert_eq!(x.len(), y.len());
let key_iter = x.iter().zip(y).map(|(x, y)| Key::new(x, y, Interpolation::Linear));
let spline = Spline::from_iter(key_iter);
let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
result
}
}
fn main() {
}
Cargo.toml
[package]
name = "name"
version = "0.1.0"
edition = "2018"
[dependencies]
conv = "0.3.2"
splines = "1.0.0-rc.3"
num-traits = "0.2"
Compilation errors:
error[E0277]: the trait bound `&T: splines::interpolate::One` is not satisfied
--> src/main.rs:18:66
|
18 | let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
| ^^^^^^ the trait `splines::interpolate::One` is not implemented for `&T`
error[E0277]: the trait bound `&T: splines::interpolate::Trigo` is not satisfied
--> src/main.rs:18:66
|
18 | let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
| ^^^^^^ the trait `splines::interpolate::Trigo` is not implemented for `&T`
error[E0277]: cannot multiply `&T` to `&T`
--> src/main.rs:18:66
|
18 | let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
| ^^^^^^ no implementation for `&T * &T`
|
= help: the trait `std::ops::Mul` is not implemented for `&T`
= help: consider adding a `where &T: std::ops::Mul` bound
error[E0277]: cannot divide `&T` by `&T`
--> src/main.rs:18:66
|
18 | let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
| ^^^^^^ no implementation for `&T / &T`
|
= help: the trait `std::ops::Div` is not implemented for `&T`
= help: consider adding a `where &T: std::ops::Div` bound
error[E0277]: the trait bound `&U: splines::interpolate::Interpolate<&T>` is not satisfied
--> src/main.rs:18:66
|
18 | let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
| ^^^^^^ the trait `splines::interpolate::Interpolate<&T>` is not implemented for `&U`
error[E0277]: cannot add `&T` to `&T`
--> src/main.rs:18:66
|
18 | let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
| ^^^^^^ no implementation for `&T + &T`
|
= help: the trait `std::ops::Add` is not implemented for `&T`
= help: consider adding a `where &T: std::ops::Add` bound
= note: required because of the requirements on the impl of `splines::interpolate::Additive` for `&T`
error[E0277]: cannot subtract `&T` from `&T`
--> src/main.rs:18:66
|
18 | let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
| ^^^^^^ no implementation for `&T - &T`
|
= help: the trait `std::ops::Sub` is not implemented for `&T`
= help: consider adding a `where &T: std::ops::Sub` bound
= note: required because of the requirements on the impl of `splines::interpolate::Additive` for `&T`
error[E0277]: the trait bound `&U: num_traits::identities::Zero` is not satisfied
--> src/main.rs:18:86
|
18 | let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
| ^^^^^^^^^^^^^^^^ the trait `num_traits::identities::Zero` is not implemented for `&U`
|
= note: required by `num_traits::identities::zero`
error[E0277]: a collection of type `std::vec::Vec<U>` cannot be built from an iterator over elements of type `&U`
--> src/main.rs:18:107
|
18 | let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
| ^^^^^^^ a collection of type `std::vec::Vec<U>` cannot be built from `std::iter::Iterator<Item=&U>`
|
= help: the trait `std::iter::FromIterator<&U>` is not implemented for `std::vec::Vec<U>`
error: aborting due to 9 previous errors
For more information about this error, try `rustc --explain E0277`.
error: Could not compile `trait_generic`.
Maybe you could just consider using Key::new(*x, *y, Interpolation::Linear) and spline.sample(*x)?

Rust "expected type" error prints mismatched types that are exactly the same

With nightly rust:
Playground
struct Foo<T, F: Fn(&T, &T) -> T> {
value: T,
func: F
}
fn main() {
let lambda = |&x, &y| x + y;
let foo = Foo {
value: 5 as i32,
func: lambda
};
}
Error message:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:8:15
|
8 | let foo = Foo {
| ^^^ one type is more general than the other
|
= note: expected type `std::ops::FnOnce<(&i32, &i32)>`
found type `std::ops::FnOnce<(&i32, &i32)>`
Note that the expected type and found type are character for character identical. Why is the error message saying that one type is more general than the other, while also saying that they are the same type?
With nightly rust:
This appears to be just a "bad" error message in a nightly build. In Rust 1.32 (stable), the errors tell you that this is a lifetime mismatch:
error[E0631]: type mismatch in closure arguments
--> src/main.rs:8:15
|
7 | let lambda = |&x, &y| x + y;
| -------------- found signature of `fn(&_, &_) -> _`
8 | let foo = Foo {
| ^^^ expected signature of `for<'r, 's> fn(&'r i32, &'s i32) -> _`
|
note: required by `Foo`
--> src/main.rs:1:1
|
1 | struct Foo<T, F: Fn(&T, &T) -> T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0271]: type mismatch resolving `for<'r, 's> <[closure#src/main.rs:7:18: 7:32] as std::ops::FnOnce<(&'r i32, &'s i32)>>::Output == i32`
--> src/main.rs:8:15
|
8 | let foo = Foo {
| ^^^ expected bound lifetime parameter, found concrete lifetime
|
note: required by `Foo`
--> src/main.rs:1:1
|
1 | struct Foo<T, F: Fn(&T, &T) -> T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Why is the error message saying that one type is more general than the other, while also saying that they are the same type?
The types differ only in lifetimes. The nightly message doesn't include lifetimes — perhaps in an attempt to reduce noise in cases where the lifetimes are not relevant. Obviously this is not at all helpful when lifetimes are the only difference between the types.
Consider reporting a bug to the Rust team.

Resources