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

Add Ref/RefMut map_split method #51466

Merged
merged 1 commit into from
Jun 17, 2018
Merged

Add Ref/RefMut map_split method #51466

merged 1 commit into from
Jun 17, 2018

Conversation

joshlf
Copy link
Contributor

@joshlf joshlf commented Jun 10, 2018

As proposed here.

TLDR: Add a map_split method that allows multiple RefMuts to exist simultaneously so long as they refer to non-overlapping regions of the original RefCell. This is useful for things like the slice split_at_mut method.

@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 Jun 10, 2018
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:03:47]    Compiling cc v1.0.15
[00:03:47]    Compiling core v0.0.0 (file:///checkout/src/libcore)
[00:03:47]    Compiling unwind v0.0.0 (file:///checkout/src/libunwind)
[00:03:47]    Compiling build_helper v0.1.0 (file:///checkout/src/build_helper)
[00:03:50] error[E0541]: unknown meta item 'since'
[00:03:50]     --> libcore/cell.rs:1145:47
[00:03:50]      |
[00:03:50] 1145 |     #[unstable(feature = "refcell_map_split", since = "0")]
[00:03:50] 
[00:03:50] 
[00:03:50] error[E0541]: unknown meta item 'since'
[00:03:50]     --> libcore/cell.rs:1231:47
[00:03:50]      |
[00:03:50] 1231 |     #[unstable(feature = "refcell_map_split", since = "0")]
[00:03:50] 
[00:03:52]    Compiling compiler_builtins v0.0.0 (file:///checkout/src/rustc/compiler_builtins_shim)
[00:03:52]    Compiling cmake v0.1.30
[00:03:52]    Compiling alloc_jemalloc v0.0.0 (file:///checkout/src/liballoc_jemalloc)
---
[00:04:00] Caused by:
[00:04:00]   process didn't exit successfully: `/checkout/obj/build/bootstrap/debug/rustc --crate-name core libcore/lib.rs --color always --error-format json --crate-type lib --emit=dep-info,link -C opt-level=2 -C metadata=e9cdce497aae9e81 -C extra-filename=-e9cdce497aae9e81 --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps --target x86_64-unknown-linux-gnu -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-std/release/deps` (exit code: 101)
[00:04:00] warning: build failed, waiting for other jobs to finish...
[00:04:11] error: build failed
[00:04:11] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "--target" "x86_64-unknown-linux-gnu" "-j" "4" "--release" "--locked" "--color" "always" "--features" "panic-unwind jemalloc backtrace" "--manifest-path" "/checkout/src/libstd/Cargo.toml" "--message-format" "json"
[00:04:11] expected success, got: exit code: 101
[00:04:11] thread 'main' panicked at 'cargo must succeed', bootstrap/compile.rs:1091:9
[00:04:11] travis_fold:end:stage0-std

[00:04:11] travis_time:end:stage0-std:start=1528609189357781357,finish=1528609213901463650,duration=24543682293


[00:04:11] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:04:11] Build completed unsuccessfully in 0:00:25
[00:04:11] Makefile:79: recipe for target 'tidy' failed
[00:04:11] make: *** [tidy] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:28c73509
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:0fc341af:start=1528609214449490020,finish=1528609214457192995,duration=7702975
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:0bfb0b72
$ head -30 ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
head: cannot open ‘./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers’ for reading: No such file or directory
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:0d561cc8
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@joshlf joshlf force-pushed the ref-split branch 2 times, most recently from 123f1f1 to 6f065e6 Compare June 10, 2018 05:44
@kennytm kennytm added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Jun 10, 2018
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[01:09:45] 
[01:09:45]    Doc-tests core
[01:09:57] 
[01:09:57] running 2079 tests
[01:10:09] ......................................F................F............................................
[01:10:39] ....................................................................................................
[01:10:55] ...............................i....................................................................
[01:11:07] ....................................................................................................
[01:11:19] ....................................................................................................
---
-linux-gnu
116828 ./obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release
116028 ./obj/build/x86_64-unknown-linux-gnu/test/mir-opt
103932 ./obj/build/bootstrap/debug/incremental/bootstrap-c730863262pt
103928 ./obj/build/bootstrap/debug/incremental/bootstrap-c730863262pt/s-f1uiq6s958-zstklu-no75lmxs5rt9
102924 ./obj/build/x86_64-unknown-linux-gnu/stage0-tools/x86_64-unknown-linux-gnu
102920 ./obj/build/x86_64-unknown-linux-gnu/stage0-tools/x86_64-unknown-linux-gnu/release
99540 ./obj/build/x86_64-unknown-linux-gnu/stage0-tools/x86_64-unknown-linux-gnu/release/deps
91392 ./obj/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

//
// `Ref` and `RefMut` are both two words in size, and so there can never be
// enough `Ref`s or `RefMut`s in existence to overflow half of the `usize`
// range. Thus, a `BorrowFlag` will never overflow.
Copy link
Member

Choose a reason for hiding this comment

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

I doubt this, since you could forget a Ref. See #25841.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call. I'll make sure that this is asserted everywhere it could overflow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, I believe I've gotten all of the cases.

@joshlf joshlf force-pushed the ref-split branch 2 times, most recently from 3ab1411 to 80bcd16 Compare June 10, 2018 07:19
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[01:16:23] 
[01:16:23]    Doc-tests core
[01:16:35] 
[01:16:35] running 2079 tests
[01:16:48] .........................................F..............F...........................................
[01:17:20] ....................................................................................................
[01:17:37] ...............................i....................................................................
[01:17:49] ....................................................................................................
[01:18:02] ....................................................................................................
---
[01:21:17] ....................................................................................................
[01:21:30] .........i.............................................i.......................
[01:21:30] failures:
[01:21:30] 
[01:21:30] ---- cell.rs - cell::Ref<'b, T>::map_split (line 1139) stdout ----
[01:21:30] error[E0658]: use of unstable library feature 'refcell_map_split'
[01:21:30]  --> cell.rs:1144:20
[01:21:30]   |
[01:21:30] 8 | let (begin, end) = Ref::map_split(borrow, |a| a.split_at(2));
[01:21:30]   |
[01:21:30]   |
[01:21:30]   = help: add #![feature(refcell_map_split)] to the crate attributes to enable
[01:21:30] 
[01:21:30] thread 'cell.rs - cell::Ref<'b, T>::map_split (line 1139)' panicked at 'couldn't compile the test', librustdoc/test.rs:325:17
[01:21:30] 
[01:21:30] ---- cell.rs - cell::RefMut<'b, T>::map_split (line 1220) stdout ----
[01:21:30] ---- cell.rs - cell::RefMut<'b, T>::map_split (line 1220) stdout ----
[01:21:30] error[E0658]: use of unstable library feature 'refcell_map_split'
[01:21:30]  --> cell.rs:1226:24
[01:21:30]   |
[01:21:30] 9 |     let (begin, end) = RefMut::map_split(borrow, |a| a.split_at_mut(2));
[01:21:30]   |
[01:21:30]   |
[01:21:30]   = help: add #![feature(refcell_map_split)] to the crate attributes to enable
[01:21:30] 
[01:21:30] thread 'cell.rs - cell::RefMut<'b, T>::map_split (line 1220)' panicked at 'couldn't compile the test', librustdoc/test.rs:325:17
[01:21:30] 
[01:21:30] failures:
[01:21:30]     cell.rs - cell::Ref<'b, T>::map_split (line 1139)
[01:21:30]     cell.rs - cell::RefMut<'b, T>::map_split (line 1220)
[01:21:30]     cell.rs - cell::RefMut<'b, T>::map_split (line 1220)
[01:21:30] 
[01:21:30] test result: FAILED. 2074 passed; 2 failed; 3 ignored; 0 measured; 0 filtered out
[01:21:30] 
[01:21:30] error: test failed, to rerun pass '--doc'
[01:21:30] 
[01:21:30] 
[01:21:30] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "test" "--target" "x86_64-unknown-linux-gnu" "-j" "4" "--release" "--locked" "--color" "always" "--features" "panic-unwind jemalloc backtrace" "--manifest-path" "/checkout/src/libstd/Cargo.toml" "-p" "core" "--" "--quiet"
[01:21:30] 
[01:21:30] 
[01:21:30] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:21:30] Build completed unsuccessfully in 0:34:19
[01:21:30] Build completed unsuccessfully in 0:34:19
[01:21:30] make: *** [check] Error 1
[01:21:30] Makefile:58: recipe for target 'check' failed

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:0a85adb8
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@Centril
Copy link
Contributor

Centril commented Jun 10, 2018

cc @RalfJung on the soundness of this (seems sound to me...)

It would be good to list more use cases this supports.
The one mentioned in the documentation can simply be written as:

let mut borrow = c.borrow_mut();
let (begin, end) = borrow.split_at_mut(2);
assert_eq!(*begin, [1, 2]);
assert_eq!(*end, [3, 4]);
begin.copy_from_slice(&[4, 3]);
end.copy_from_slice(&[2, 1]);

which seems more direct.

Copy link
Contributor

@Centril Centril left a comment

Choose a reason for hiding this comment

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

Some improvement suggestions for documentation.

/// ```
/// use std::cell::{Ref, RefCell};
///
/// let c = RefCell::new([1, 2, 3, 4]);
Copy link
Contributor

Choose a reason for hiding this comment

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

s/c/cell
s/a/slice

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

/// ```
/// use std::cell::{RefCell, RefMut};
///
/// let c = RefCell::new([1, 2, 3, 4]);
Copy link
Contributor

Choose a reason for hiding this comment

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

s/c/cell
s/a/slice

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@kennytm kennytm added the T-lang Relevant to the language team, which will review and decide on the PR/issue. label Jun 10, 2018
@shepmaster
Copy link
Member

Too deep for me!

r? @dtolnay

@rust-highfive rust-highfive assigned dtolnay and unassigned shepmaster Jun 10, 2018
@ExpHP
Copy link
Contributor

ExpHP commented Jun 10, 2018

Why (U, U) instead of (U, V)?

// be enough `Ref`s or `RefMut`s in existence to overflow half of the `usize`
// range. Thus, a `BorrowFlag` will probably never overflow. However, this is
// not a guarantee, as a pathological program could repeatedly create and then
// mem::drop `Ref`s or `RefMut`s. Thus, all code must explicitly check for
Copy link
Member

Choose a reason for hiding this comment

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

I believe the trouble arises from mem::forget, not mem::drop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@dtolnay
Copy link
Member

dtolnay commented Jun 10, 2018

The implementation looks good to me. I agree that after split they should be able to have different types U, V.

@joshlf
Copy link
Contributor Author

joshlf commented Jun 10, 2018

Why (U, U) instead of (U, V)?

Done.

Is there any canonical way to have the function return an arbitrary number of elements in the tuple (or at least, up to some reasonable bound, like 8)? I have a function called extract_range which has the signature extract_range<R: RangeBounds<usize>>(&mut [u8], range: R) -> (&mut [u8], &mut [u8], &mut [u8]), and I could imagine others having similar functions.

/// assert_eq!(*begin, [1, 2]);
/// assert_eq!(*end, [3, 4]);
/// ```
#[unstable(feature = "refcell_map_split", issue = "51466")]
Copy link
Member

Choose a reason for hiding this comment

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

Please file a tracking issue separate from the PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done: #51476

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.

[00:04:46] travis_fold:start:tidy
travis_time:start:tidy
tidy check
[00:04:46] tidy error: /checkout/src/libcore/cell.rs:1235: line longer than 100 chars
[00:04:48] some tidy checks failed
[00:04:48] 
[00:04:48] 
[00:04:48] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:04:48] 
[00:04:48] 
[00:04:48] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:04:48] Build completed unsuccessfully in 0:01:44
[00:04:48] Build completed unsuccessfully in 0:01:44
[00:04:48] Makefile:79: recipe for target 'tidy' failed
[00:04:48] make: *** [tidy] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:1f9f2576
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:064dc514:start=1528650682346797564,finish=1528650682352809085,duration=6011521
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:008be7d6
$ head -30 ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
head: cannot open ‘./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers’ for reading: No such file or directory
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:0b4cffe0
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@ExpHP
Copy link
Contributor

ExpHP commented Jun 10, 2018

extract_range<R: RangeBounds<usize>>(&mut [u8], range: R) -> (&mut [u8], &mut [u8], &mut [u8])

I was thinking of this myself. This is much like the issue faced by unzip, where the function that deals with 2 collections is incapable of being used as a building block for dealing with more than 2 collections.

Libraries often solve this sort of problem by making a trait for the output type and implementing it for many tuple sizes (or implementing it on a small set of combinator types), but I seldom see this in the standard library... almost as though we're waiting for variadic generics (yet nobody wants to admit it!).

@joshlf
Copy link
Contributor Author

joshlf commented Jun 10, 2018

I was thinking of this myself. This is much like the issue faced by unzip, where the function that deals with 2 collections is incapable of being used as a building block for dealing with more than 2 collections. Libraries often solve this sort of problem by making a trait for the output type and implementing it for many tuple sizes (or implementing it on a small set of combinator types), but I seldom see this in the standard library... almost as though we're waiting for variadic generics (yet nobody wants to admit it!).

I'm happy to merge this as is and just keep an eye out for being able to add something like map_split_many in the future once we have a better mechanism for it.

@ExpHP
Copy link
Contributor

ExpHP commented Jun 10, 2018

It does make me wonder though if perhaps the standard library should simply expose a low-level API for this; one which might not be very ergonomic (it might even be unsafe), but which could be used to implement a method like map_split (for possibly more than 2 items) in a third-party crate.

(that said, doing so would ironically come at a much greater design cost, as care must be taken not to place unnecessary constraints on future evolution of the type)


Edit: Of course, I guess there's no real reason map_split couldn't come first. If two values are enough for most people, that's great! It's just that, once you need three things (and discover that there is literally no way), I think it'll feel half-baked.

@bors
Copy link
Contributor

bors commented Jun 17, 2018

⌛ Testing commit 2a999b4 with merge 7df0770a97fce4eb8c8c4282ae7f05fe22731328...

@bors
Copy link
Contributor

bors commented Jun 17, 2018

💔 Test failed - status-travis

@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 Jun 17, 2018
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-distcheck of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[02:08:44] warning: spurious network error (2 tries remaining): curl error: Couldn't resolve host 'github.com'
[02:08:44] ; class=Net (12)
[02:09:41] warning: spurious network error (1 tries remaining): curl error: Couldn't resolve host 'github.com'
[02:09:41] ; class=Net (12)
[02:10:37] error: failed to load source for a dependency on `rand`
[02:10:37] Caused by:
[02:10:37]   Unable to update registry `https://github.com/rust-lang/crates.io-index`
[02:10:37] 
[02:10:37] Caused by:
[02:10:37] Caused by:
[02:10:37]   failed to fetch `https://github.com/rust-lang/crates.io-index`
[02:10:37] 
[02:10:37] Caused by:
[02:10:37]   curl error: Couldn't resolve host 'github.com'
[02:10:37] ; class=Net (12)
[02:10:37] 
[02:10:37] 
[02:10:37] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "generate-lockfile" "--manifest-path" "/checkout/obj/build/tmp/distcheck-src/rust-src/lib/rustlib/src/rust/src/libstd/Cargo.toml"
[02:10:37] 
[02:10:37] 
[02:10:37] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test distcheck
[02:10:37] Build completed unsuccessfully in 2:07:36

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-distcheck of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[02:08:44] warning: spurious network error (2 tries remaining): curl error: Couldn't resolve host 'github.com'
[02:08:44] ; class=Net (12)
[02:09:41] warning: spurious network error (1 tries remaining): curl error: Couldn't resolve host 'github.com'
[02:09:41] ; class=Net (12)
[02:10:37] error: failed to load source for a dependency on `rand`
[02:10:37] Caused by:
[02:10:37]   Unable to update registry `https://github.com/rust-lang/crates.io-index`
[02:10:37] 
[02:10:37] Caused by:
[02:10:37] Caused by:
[02:10:37]   failed to fetch `https://github.com/rust-lang/crates.io-index`
[02:10:37] 
[02:10:37] Caused by:
[02:10:37]   curl error: Couldn't resolve host 'github.com'
[02:10:37] ; class=Net (12)
[02:10:37] 
[02:10:37] 
[02:10:37] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "generate-lockfile" "--manifest-path" "/checkout/obj/build/tmp/distcheck-src/rust-src/lib/rustlib/src/rust/src/libstd/Cargo.toml"
[02:10:37] 
[02:10:37] 
[02:10:37] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test distcheck
[02:10:37] Build completed unsuccessfully in 2:07:36
---
travis_time:end:29f69a79:start=1529219337275068552,finish=1529219337281704535,duration=6635983
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:08d229f6
$ head -30 ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
head: cannot open ‘./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers’ for reading: No such file or directory
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:1d9e907a
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@kennytm
Copy link
Member

kennytm commented Jun 17, 2018

@bors retry travis-ci/travis-ci#9696

@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 Jun 17, 2018
bors added a commit that referenced this pull request Jun 17, 2018
Add Ref/RefMut map_split method

As proposed [here](https://internals.rust-lang.org/t/make-refcell-support-slice-splitting/7707).

TLDR: Add a `map_split` method that allows multiple `RefMut`s to exist simultaneously so long as they refer to non-overlapping regions of the original `RefCell`. This is useful for things like the slice `split_at_mut` method.
@bors
Copy link
Contributor

bors commented Jun 17, 2018

⌛ Testing commit 2a999b4 with merge aec00f9...

@bors
Copy link
Contributor

bors commented Jun 17, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: dtolnay
Pushing aec00f9 to master...

@bors bors merged commit 2a999b4 into rust-lang:master Jun 17, 2018
@joshlf joshlf deleted the ref-split branch June 17, 2018 16:50
@nnethercote
Copy link
Contributor

This PR regressed compile time significantly, as shown by http://perf.rust-lang.org/compare.html?start=0f8f4903f73a21d7f408870551c08acd051abeb0&end=aec00f97e1cdcea2b079e209a7e759201ba6ca7c&stat=instructions:u

Almost all benchmarks in rustc-perf were affected, the worst by 4%.

@joshlf: Can you investigate?

CC @rust-lang/wg-compiler-performance

bors added a commit that referenced this pull request Jun 19, 2018
Optimize RefCell refcount tracking

Address the performance concern raised in #51466 (comment)

cc @dtolnay  @nnethercote @rust-lang/wg-compiler-performance

cc @RalfJung @jhjourdan for soundness concerns

Can somebody kick off a perf run on this? I'm not sure how that's done, but I understand it has to be started manually.

The idea of this change is to switch to representing mutable refcount as values below 0 to eliminate some branching that was required with the old algorithm.
bors added a commit that referenced this pull request Jun 19, 2018
Optimize RefCell refcount tracking

Address the performance concern raised in #51466 (comment)

cc @dtolnay  @nnethercote @rust-lang/wg-compiler-performance

cc @RalfJung @jhjourdan for soundness concerns

Can somebody kick off a perf run on this? I'm not sure how that's done, but I understand it has to be started manually.

The idea of this change is to switch to representing mutable refcount as values below 0 to eliminate some branching that was required with the old algorithm.
joshlf pushed a commit to joshlf/rust that referenced this pull request Jun 19, 2018
Add Ref/RefMut map_split method

As proposed [here](https://internals.rust-lang.org/t/make-refcell-support-slice-splitting/7707).

TLDR: Add a `map_split` method that allows multiple `RefMut`s to exist simultaneously so long as they refer to non-overlapping regions of the original `RefCell`. This is useful for things like the slice `split_at_mut` method.
bors added a commit that referenced this pull request Jun 20, 2018
DO NOT MERGE: map_split perf test

This PR represents the cherry-pick of #51466 and #51630 onto [b81da2](b81da27) (the commit just before #51466). Comparing the performance of this PR to the performance of b81da2 should give us an apples-to-apples comparison of the optimized version of `map_split` against a previous world in which `map_split` doesn't exist, and refcounts can only represent a single writing reference.

cc @nnethercote @rkruppe @RalfJung @kennytm
bors added a commit that referenced this pull request Jun 27, 2018
Optimize RefCell refcount tracking

Address the performance concern raised in #51466 (comment)

cc @dtolnay  @nnethercote @rust-lang/wg-compiler-performance

cc @RalfJung @jhjourdan for soundness concerns

Can somebody kick off a perf run on this? I'm not sure how that's done, but I understand it has to be started manually.

The idea of this change is to switch to representing mutable refcount as values below 0 to eliminate some branching that was required with the old algorithm.
bors added a commit that referenced this pull request Jun 28, 2018
Optimize RefCell refcount tracking

Address the performance concern raised in #51466 (comment)

cc @dtolnay  @nnethercote @rust-lang/wg-compiler-performance

cc @RalfJung @jhjourdan for soundness concerns

Can somebody kick off a perf run on this? I'm not sure how that's done, but I understand it has to be started manually.

The idea of this change is to switch to representing mutable refcount as values below 0 to eliminate some branching that was required with the old algorithm.
@joshlf
Copy link
Contributor Author

joshlf commented Jun 28, 2018

@nnethercote 's concern has been addressed in #51630.

@dtolnay dtolnay assigned dtolnay and unassigned joshtriplett Mar 24, 2024
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. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet