You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Auto merge of #65385 - matthewjasper:drop-on-into-panic-otp, r=<try>
[WIP] Make `into` schedule drop for the destination again
#61430 triggered some degenerate behavior in llvm where it would inline functions far too aggressively.
This is marked as WIP because it doesn't really solve the problem in general. I've opened this PR more so that there's a place to discuss fixes.
<details>
<summary>Minimized example of the problem</summary>
Uncommenting the `#[inline]` will cause this to take a long time to compile on nightly, since llvm will inline all of the next calls into one enormous function that it spends a very long time handling.
```rust
pub trait Iterator {
type Item;
fn next(&mut self) -> Self::Item;
}
pub struct Empty;
impl Iterator for Empty {
type Item = ();
fn next(&mut self) {}
}
pub struct Chain<A, B=Empty> {
a: A,
b: B,
state: ChainState,
}
#[allow(dead_code)]
enum ChainState {
Both,
Front,
Back,
}
impl<A, B> Iterator for Chain<A, B> where
A: Iterator,
B: Iterator<Item = A::Item>
{
type Item = A::Item;
//#[inline]
//^ uncomment me for degenerate llvm behvaiour with `-O`
fn next(&mut self) -> A::Item {
let ret;
match self.state {
ChainState::Both => {
let _x = self.a.next();
self.state = ChainState::Back;
ret = self.b.next()
},
ChainState::Front => ret = self.a.next(),
ChainState::Back => ret = self.b.next(),
};
ret
}
}
type Chain2<T> = Chain<Chain<T>>;
type Chain4<T> = Chain2<Chain2<T>>;
type Chain8<T> = Chain4<Chain4<T>>;
type Chain16<T> = Chain8<Chain8<T>>;
pub fn call_next(x: &mut Chain16<Empty>) {
x.next()
}
```
</details>
Closes#47949
0 commit comments