Open
Description
Code
use std::ops::Mul;
struct Stuff{
a: i128
}
impl Mul<i64> for Stuff {
type Output = Stuff;
fn mul (self, other: i64) -> Stuff {
Stuff{a: self.a * (other as i128)}
}
}
impl Mul<i32> for Stuff {
type Output = Stuff;
fn mul (self, other: i32) -> Stuff {
Stuff{a: self.a * (other as i128)}
}
}
fn main() {
let stuff = Stuff{a: 42};
let y = stuff * 2; // Note: if I specify y's type or 2's type, it compiles.
println!("{:?}", y.a);
}
Current output
error[E0282]: type annotations needed
--> src/main.rs:25:9
|
25 | let y = stuff * 2;
| ^
26 |
27 | println!("{:?}", y.a);
| - type must be known at this point
|
help: consider giving `y` an explicit type
|
25 | let y: /* Type */ = stuff * 2;
| ++++++++++++
For more information about this error, try `rustc --explain E0282`.
Desired output
It should compile.
Rationale and extra context
Following https://doc.rust-lang.org/reference/expressions/literal-expr.html#integer-literal-expressions I think the compiler should be able to infer that 2
is an i32
and compile my program.
Alternatively, regardless of 2
's type, y
can only be a Stuff
, so this precision should be unnecessary and the compiler should compile my program.
Other cases
The following modifications compile:
- The program modified according to the compiler's suggestion (adding
Stuff
asy
's type). (code below) - Displaying
y
instead ofy.a
. (code below) - Changing
2
to2i32
or2i64
. (no code below)
The compiler suggestion (compiles):
use std::ops::Mul;
struct Stuff{
a: i128
}
impl Mul<i64> for Stuff {
type Output = Stuff;
fn mul (self, other: i64) -> Stuff {
Stuff{a: self.a * (other as i128)}
}
}
impl Mul<i32> for Stuff {
type Output = Stuff;
fn mul (self, other: i32) -> Stuff {
Stuff{a: self.a * (other as i128)}
}
}
fn main() {
let stuff = Stuff{a: 42};
let y: Stuff = stuff * 2; // This is the change the compiler suggests, and it works.
println!("{:?}", y.a);
}
Displaying y
instead of y.a
(compiles too):
use std::ops::Mul;
#[derive(Debug)] // First change in this code snippet
struct Stuff{
a: i128
}
impl Mul<i64> for Stuff {
type Output = Stuff;
fn mul (self, other: i64) -> Stuff {
Stuff{a: self.a * (other as i128)}
}
}
impl Mul<i32> for Stuff {
type Output = Stuff;
fn mul (self, other: i32) -> Stuff {
Stuff{a: self.a * (other as i128)}
}
}
fn main() {
let stuff = Stuff{a: 42};
let y = stuff * 2;
println!("{:?}", y); // 2nd change, I display y instead of y.a
}
Rust Version
rustc 1.80.1 (3f5fd8dd4 2024-08-06)
binary: rustc
commit-hash: 3f5fd8dd41153bc5fdca9427e9e05be2c767ba23
commit-date: 2024-08-06
host: x86_64-unknown-linux-gnu
release: 1.80.1
LLVM version: 18.1.7
Anything else?
It also causes the same compiler diagnostic on 1.79.0