-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crash from iterator returning borrowed reference #22886
Comments
Confirmed with
|
I think @nikomatsakis comment from #22077 also applies here. Quote:
|
Yeah, the idea that you could return a value of type fn crash_please() {
let mut iter = Newtype {
option: Some(Box::new(0)),
marker: (),
};
let saved = iter.next().unwrap();
println!("{}", saved);
iter.option = None;
println!("{}", saved);
}
struct Newtype<'a, T: 'a> {
option: Option<Box<usize>>,
marker: T,
}
impl<'a, T> Iterator for Newtype<'a, T> {
type Item = &'a Box<usize>;
fn next(&mut self) -> Option<&Box<usize>> {
self.option.as_ref()
}
} |
On Sat, Feb 28, 2015 at 05:56:36AM -0800, Edward Wang wrote:
I'll try to make a PR for this, I've just been debating how hard core |
@tov what version of rustc are you using? I don't expect that code to compile these days, because the |
@tov see e.g. http://is.gd/6ALz11 (which yields a compilation error) this changed as part of https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md |
Also, if we change the example to constrain the |
Duplicate of #22077. Leaving open for tracking of this thread of conversation, but removing nomination tag. |
This errors correctly on nightly and stable. |
With an iterator that returns a borrowed reference to its contents, it’s possible to hold the reference longer than the reference is valid. In particular, if the iterator changes its internal state, the new state can be observed via the saved reference. Check it out:
This clearly shouldn’t type check, but it does, and runs, and crashes:
Where the type error should be, I’m not sure. It seems like it’s actually a problem with traits. If we change the above code to define
next
in a non-trait impl, then it no longer passes the borrow checker:I originally observed this bug when testing an iterator that owns a
String
; at each iteration it modifies the string and then returns a string slice borrowed from it. My non-test code worked fine because it finished with each value from the iterator before callingnext()
again, but the test code collected the iterator into a vector. This meant that all the slices in the vector continued to point to the same buffer, even after it had been modified. So for example, if the strings written to the buffer were"aaa"
,"bb"
, and"c"
, then in the end the vector would contain"cba"
,"cb"
, and"b"
. Creepy.Version
I’m using 1.0.0-alpha still, because I’m teaching a class and we don’t want to follow a moving target, but I confirmed that the Feb. 26 nightly has the same bug.
The text was updated successfully, but these errors were encountered: