Skip to content
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

Fix some aliasing issues in Vec #70558

Merged
merged 9 commits into from
Apr 5, 2020
Merged

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented Mar 30, 2020

Vec::extend and Vec::truncate invalidated references into the vector even without reallocation, because they (implicitly) created a mutable reference covering the entire initialized part of the vector.

Fixes #70301
I verified the fix by adding some new tests here that I ran in Miri.

@rust-highfive
Copy link
Collaborator

r? @shepmaster

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 30, 2020
self.set_len(len + slice.len());
self.get_unchecked_mut(len..).copy_from_slice(slice);
Copy link
Member Author

@RalfJung RalfJung Mar 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately there is no good way to grep for all places where the implicit DerefMut coercion is used, like here. I grepped for get_unchecked_mut and get_unchecked and got rid of those.

Copy link
Contributor

@elichai elichai Apr 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could maybe print the backtrace in the DerefMut implementation and then run the tests and it will print what functions call DerefMut?(locally obviously hehe)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since DerefMut is called for every mutable indexing operation (&mut v[i]), I expect that to show tons of stacktraces and not be very useful.

@RalfJung RalfJung force-pushed the vec-extend-aliasing branch 2 times, most recently from a5aea87 to d959640 Compare March 30, 2020 10:10
also add smoke test to detect relocation even in rustc runs
@Centril
Copy link
Contributor

Centril commented Mar 30, 2020

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion

@bors
Copy link
Contributor

bors commented Mar 30, 2020

⌛ Trying commit 4eacf45 with merge fd566c8d8da22c80354a2256fdce4fa836e1f906...

@RalfJung
Copy link
Member Author

Let's re-try that with the latest changes. I think now I have all &mut self methods that are not expected to change the capacity covered in the test (and found and fixed issues in remove and swap_remove).

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion

@bors
Copy link
Contributor

bors commented Mar 30, 2020

⌛ Trying commit 5bbaac3 with merge c5fdda00c8e50fa1bacea8d98dd211fcac521372...

@bors
Copy link
Contributor

bors commented Mar 30, 2020

☀️ Try build successful - checks-azure
Build commit: c5fdda00c8e50fa1bacea8d98dd211fcac521372 (c5fdda00c8e50fa1bacea8d98dd211fcac521372)

@rust-timer
Copy link
Collaborator

Queued c5fdda00c8e50fa1bacea8d98dd211fcac521372 with parent 8926bb4, future comparison URL.

@llogiq
Copy link
Contributor

llogiq commented Mar 30, 2020

Would a lint for implicit deref(_mut) help?

@rust-timer
Copy link
Collaborator

Finished benchmarking try commit c5fdda00c8e50fa1bacea8d98dd211fcac521372, comparison URL.

@RalfJung
Copy link
Member Author

RalfJung commented Mar 31, 2020

Perf looks green, except for "syn-opt" where some runs get faster by 3% and some slower by 2% -- but they have a ? so I suppose those are pretty noisy anyway.

@llogiq hm, good idea. I am not sure, there might be tons of harmless implicit derefs in that file. The problematic ones are the ones for Vec itself.

But it might be worth a shot.

@@ -962,13 +963,15 @@ impl<T> Vec<T> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn swap_remove(&mut self, index: usize) -> T {
let len = self.len();
assert!(index < len, "index out of bounds: the len is {} but the index is {}", len, index);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using formatting in the error seems to cause performance issues; let me know if you'd prefer an unformatted message.

@Amanieu
Copy link
Member

Amanieu commented Apr 4, 2020

The changes look fine, and there doesn't seem to be any perf impact.

@bors r+

@bors
Copy link
Contributor

bors commented Apr 4, 2020

📌 Commit 3e2ac9c000cefd624d0324f7ffb16457d6246b72 has been approved by Amanieu

@bors
Copy link
Contributor

bors commented Apr 4, 2020

🌲 The tree is currently closed for pull requests below priority 1000, this pull request will be tested once the tree is reopened

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 4, 2020
@bors
Copy link
Contributor

bors commented Apr 5, 2020

⌛ Testing commit 3e2ac9c000cefd624d0324f7ffb16457d6246b72 with merge e094a03952477c60b97b8fc3535872714749bec2...

@bors

This comment has been minimized.

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Apr 5, 2020
@RalfJung
Copy link
Member Author

RalfJung commented Apr 5, 2020

##[error]An error occurred while provisioning resources (Error Type: Disconnect).

@bors retry

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 5, 2020
@RalfJung
Copy link
Member Author

RalfJung commented Apr 5, 2020

The changes look fine, and there doesn't seem to be any perf impact.

That perf measurement was from before I added the panic message.
I'll make this an assertion now and once #70573 lands, make swap_remove match remove.

@RalfJung
Copy link
Member Author

RalfJung commented Apr 5, 2020

r? @Amanieu @bors r=Amanieu

@rust-highfive rust-highfive assigned Amanieu and unassigned shepmaster Apr 5, 2020
@bors
Copy link
Contributor

bors commented Apr 5, 2020

📌 Commit 7e81c11 has been approved by Amanieu

bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 5, 2020
Rollup of 5 pull requests

Successful merges:

 - rust-lang#70558 (Fix some aliasing issues in Vec)
 - rust-lang#70760 (docs: make the description of Result::map_or more clear)
 - rust-lang#70769 (Miri: remove an outdated FIXME)
 - rust-lang#70776 (clarify comment in RawVec::into_box)
 - rust-lang#70806 (fix Miri assignment sanity check)

Failed merges:

r? @ghost
@bors bors merged commit 7e4ed72 into rust-lang:master Apr 5, 2020
@RalfJung RalfJung deleted the vec-extend-aliasing branch April 5, 2020 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

String::push_str invalidates interior references even when it does not reallocate
9 participants