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
{{ message }}
Repository navigation
Stack overflow when bounding FnOnce with Send + 'static #23003
I'm not exactly sure what is happening, but I thought I would file an issue. I am attempting to update syncbox (https://github.com/carllerche/syncbox). I have to add 'static bounds to types that were previously only bound by Send, however it seems to be causing stack overflow errors in rustc.
I could not make a simple repro, but here is the code in a single file:
Just FYI, you can workaround the problem by removing the A:Async bound from Receipt. What happens is that, per #22246, for Result<A> to be legal in some context with lifetime 'x, it winds up requiring that A::Cancel :'x, which in turn isresult : 'x`. Probably the fix is just to check that we don't reach the same type again. This wasn't necessary before because types were always of finite size.
So adding a cache is probably the way to fix this crash. What worries me is that the set of types might be ever-expanding. We could add a recursion depth to counter that but it feels like it might rule out potentially legitimate types? I guess they can probably always be phrased differently. Let me try to work up a concrete example of what I mean.
use std::marker::PhantomData;traitAsync{typeCancel;}structReceipt<A:Async>{marker:PhantomData<A>,}structComplete{core:Option<()>,}implAsyncforComplete{typeCancel = Receipt<Complete>;}fnfoo(r:Receipt<Complete>){}fnmain(){}
This variant generates (at least in my version, which contains a fix for the above issue), an overflow error:
use std::marker::PhantomData;traitAsync{typeCancel;}structReceipt<A:Async>{marker:PhantomData<A>,}structComplete<B>{core:Option<B>,}impl<B>AsyncforComplete<B>{typeCancel = Receipt<Complete<Option<B>>>;}fnfoo(r:Receipt<Complete<()>>){}fnmain(){}
The reason is because Complete<()>::Cancel, normalized, is Receipt<Complete<Option<()>>>, which in turn expands out to Receipt<Complete<Option<Option<()>>>> and so forth.
I am not sure if this overflow error is entirely legitimate -- by which I mean, it falls out of the rules as we have them today, but it doesn't feel entirely necessary.
Okay! As such, let's add e-needstest, and let's get a test for @nikomatsakis 's last code block as a representatitve of this issue. I'd be happy to help anyone who wants to tackle this.
Activity
carllerche commentedon Mar 3, 2015
mr. @alexcrichton has used creduce to reduce the case:
nikomatsakis commentedon Mar 3, 2015
This was caused by fixing #22246 (PR #22436 in particular). I have to think on what's the best fix here.
nikomatsakis commentedon Mar 3, 2015
Just FYI, you can workaround the problem by removing the
A:Asyncbound fromReceipt. What happens is that, per #22246, forResult<A>to be legal in some context with lifetime'x, it winds up requiring thatA::Cancel :'x, which in turn isresult : 'x`. Probably the fix is just to check that we don't reach the same type again. This wasn't necessary before because types were always of finite size.nikomatsakis commentedon Mar 3, 2015
So adding a cache is probably the way to fix this crash. What worries me is that the set of types might be ever-expanding. We could add a recursion depth to counter that but it feels like it might rule out potentially legitimate types? I guess they can probably always be phrased differently. Let me try to work up a concrete example of what I mean.
nikomatsakis commentedon Mar 3, 2015
Reduced more:
nikomatsakis commentedon Mar 4, 2015
This variant generates (at least in my version, which contains a fix for the above issue), an overflow error:
The reason is because
Complete<()>::Cancel, normalized, isReceipt<Complete<Option<()>>>, which in turn expands out toReceipt<Complete<Option<Option<()>>>>and so forth.I am not sure if this overflow error is entirely legitimate -- by which I mean, it falls out of the rules as we have them today, but it doesn't feel entirely necessary.
When generating WF criteria, do not visit the same type more than
Rollup merge of rust-lang#23013 - nikomatsakis:syncbox, r=pnkfelix
Rollup merge of rust-lang#23013 - nikomatsakis:syncbox, r=pnkfelix
arielb1 commentedon Mar 5, 2015
A mutated version (without
Sized) causes a rustc stack overflow/illegal instruction:The overflow is weird, because you can have
impl<T> Foo for S<T> { type Ty = S<Option<T>>; }frewsxcv commentedon Apr 25, 2015
This is still an issue using Rust 1.0 beta 2
Full error message (compiling @nikomatsakis's latest code block): https://gist.githubusercontent.com/frewsxcv/c74c589b42675c5e5df7/raw/f0d4224d119fcf51db9d48c83fa266c0e955f4bd/gistfile1.txt
frewsxcv commentedon Apr 25, 2015
The I-ICE label can probably be removed, unless there is still an ICE issue here
apasel422 commentedon Oct 24, 2015
It appears that all example code in this issue now compiles on nightly.
steveklabnik commentedon Oct 24, 2015
Okay! As such, let's add e-needstest, and let's get a test for @nikomatsakis 's last code block as a representatitve of this issue. I'd be happy to help anyone who wants to tackle this.
apasel422 commentedon Oct 25, 2015
This actually has a test already in src/test/run-pass/traits-issue-23003.rs and can be closed.
Merge pull request rust-lang#23003 from A4-Tacks/coerce-func-param-comp