Reputation: 1
I'm trying to understand how does Rust compiler infer types but I cannot give an answer to the following problem: within the main I got two different behaviours that differ by the use of clone trait rather than the copy one. In the first case (I commented the lines belonging to this case) the compiler cannot infer the type for s variable (I have to specify let s: *S* = 42.into()
), while in the second one it can.
#[derive(Debug)]
struct S{
i: i32
}
impl From<i32> for S {
fn from(value: i32) -> Self {
S {
i: value
}
}
}
impl Clone for S{
fn clone(&self) -> S {
S{
i: self.i,
}
}
}
impl Copy for S{
}
fn main(){
let mut v = Vec::<S>::new();
let s = 42.into();
//let s: S = 42.into();
for i in 0..3 {
//let clone = s.clone();
//v.push(clone)
v.push(s);
}
println!("{:?}", v);
}
Does anyone know why?
Upvotes: 0
Views: 66
Reputation: 125835
If you don't annotate the result of 42.into()
, the compiler will attempt to infer it.
You then call some .clone()
method upon that result. But there could be many possible .clone()
methods, e.g. an intrinsic one and ones from in-scope traits.
Whilst the compiler knows which traits are in-scope, and arguably could search through them to discover if the .clone()
method call can come from at most one of them, that still would not rule out the possibility of some type's intrinsic method having been intended instead; furthermore, such inference would be a stability hazard should such traits be added/removed from scope in future. Therefore the compiler doesn't undertake such guesswork.
Instead it requires either that the type be annotated as you have found, or else that the method call be unambiguous (in which case it can then infer from its signature that s
must have type S
):
#[derive(Clone, Copy, Debug)]
pub struct S {
pub i: i32
}
impl From<i32> for S {
fn from(i: i32) -> Self {
Self { i }
}
}
fn main(){
let mut v = Vec::<S>::new();
let s = 42.into();
for _ in 0..3 {
let clone = Clone::clone(&s); // <-- this call is unambiguous
v.push(clone);
}
println!("{:?}", v);
}
Upvotes: 2