Description
I tried this code:
pub fn largest_rectangle_area(heights: Vec<i32>) -> i32 {
let mut widths = vec![(0usize, heights.len()); heights.len()];
let mut stack = vec![];
for (idx, &x) in heights.iter().enumerate() {
while let Some(&pos) = stack.last() {
if x >= heights[pos] {
break;
}
widths[pos].1 = idx;
stack.pop();
}
stack.push(idx);
}
todo!()
}
I expected to see this happen:
The code should have compiled without errors
Instead, this happened:
error[E0282]: type annotations needed
--> src/lib.rs:11:13
|
11 | widths[pos].1 = idx;
| ^^^^^^^^^^^ cannot infer type
|
= note: type must be known at this point
Meta
I've checked with 1.45 stable, 1.56 stable, 1.57 beta , 1.58 nightly
rustc --version --verbose
:
`--> rustc --version --verbose
rustc 1.56.0 (09c42c458 2021-10-18)
binary: rustc
commit-hash: 09c42c45858d5f3aedfa670698275303a3d19afa
commit-date: 2021-10-18
host: x86_64-apple-darwin
release: 1.56.0
LLVM version: 13.0.0
Additional information
If I change widths[pos].1 = idx
to widths[pos] = (0, idx)
the code compiles fine:
pub fn largest_rectangle_area(heights: Vec<i32>) -> i32 {
let mut widths = vec![(0, heights.len()); heights.len()];
let mut stack = vec![];
for (idx, &x) in heights.iter().enumerate() {
while let Some(&pos) = stack.last() {
if x >= heights[pos] {
break;
}
widths[pos] = (0, idx); // now it compiles fine
stack.pop();
}
stack.push(idx);
}
todo!()
}
It also compiles fine if I add type annotations for the stack
variable, which should be Vec<usize>
as its content is comming from .enumerate()
:
pub fn largest_rectangle_area(heights: Vec<i32>) -> i32 {
let mut widths = vec![(0, heights.len()); heights.len()];
let mut stack: Vec<usize> = vec![];
for (idx, &x) in heights.iter().enumerate() {
while let Some(&pos) = stack.last() {
if x >= heights[pos] {
break;
}
widths[pos].1 = idx; // now it compiles fine
stack.pop();
}
stack.push(idx);
}
todo!()
}
It also compiles fine if I add type annotations for widths
like that, but fails with the same error without that type annotation.
pub fn largest_rectangle_area(heights: Vec<i32>) -> i32 {
let mut widths = vec![(0, heights.len()); heights.len()];
let mut stack = vec![];
for (idx, &x) in heights.iter().enumerate() {
while let Some(&pos) = stack.last() {
if x >= heights[pos] {
break;
}
let at_pos: &mut (usize, usize) = &mut widths[pos]; // type annotations added here
at_pos.1 = idx;
stack.pop();
}
stack.push(idx);
}
todo!()
}
So at the end I'm not sure If it fails to infer the type of pos
or the type of widths
A user at StackOverflow managed to create the following smaller reproducible example:
fn some_fn() {
let mut widths = vec![(0usize, 0usize); 100];
let mut stack = vec![];
//let mut stack:Vec<usize> = vec![]; //why explicit type definition is needed
let a = stack.pop().unwrap();
let idx = 0usize;
widths[a].1 = idx;
stack.push(idx);
}
Here is the SO question for reference: https://stackoverflow.com/questions/69696784/cannot-infer-type-type-annotations-needed-but-the-type-is-already-known