I've been practicing on LC where I hit the following issue.
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!()
}
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
What's even stranger is that if I do a widths[pos] = (0, idx); first, then the error disappears:
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); // do a full update
stack.pop();
}
stack.push(idx);
}
stack.clear();
for (idx, &x) in heights.iter().enumerate().rev() {
while let Some(&pos) = stack.last() {
if x >= heights[pos] {
break;
}
widths[pos].0 = idx + 1; // now it's fine to use `.0`
stack.pop();
}
stack.push(idx);
}
todo!()
}
Am I missing something, or is this a bug in the compiler ?
Update
@ Ömer Erden discovered, that it fails to infer the type of pos which should be usize as it's coming from enumerate() indirectly.
It seems pretty strange because it fails to infer the type of pos when doing widths[pos].1 = idx;, but succeeds when doing widths[pos] = (0, idx);
He also managed to create more minimal MCVE:
fn _some_fn() {
let mut widths = vec![(0usize, 0usize); 100];
let mut stack = vec![];
//let mut stack:Vec<usize> = vec![]; //why explicit type definition needed
let a = stack.pop().unwrap();
let idx = 0usize;
widths[a].1 = idx;
stack.push(idx);
}