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 [T]::as_ptr_range() and [T]::as_mut_ptr_range(). #65806

Merged
merged 4 commits into from
Oct 25, 2019

Conversation

m-ou-se
Copy link
Member

@m-ou-se m-ou-se commented Oct 25, 2019

Implementation of rust-lang/rfcs#2791

@rust-highfive

This comment has been minimized.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 25, 2019
@Centril
Copy link
Contributor

Centril commented Oct 25, 2019

r? @Centril

src/libcore/slice/mod.rs Outdated Show resolved Hide resolved
#[inline]
pub fn as_ptr_range(&self) -> Range<*const T> {
let start = self.as_ptr();
let end = unsafe { start.add(self.len()) };
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please provide a brief safety argument reasoning around the requirements .add states. (Notably, vec.as_ptr().add(vec.len()) is mentioned.) (Same below.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm, now I'm starting to wonder if it actually is safe. A Vec is never larger than isize::MAX bytes, but that guarantee is not there for [T], is it?

Copy link
Member Author

@m-ou-se m-ou-se Oct 25, 2019

Choose a reason for hiding this comment

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

I changed it to wrapping_add instead.

Copy link
Contributor

@CryZe CryZe Oct 25, 2019

Choose a reason for hiding this comment

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

Mmh, I'm wondering where this limitation with isize::MAX is coming from. The documentation doesn't seem to mention why that is, only that this is the case. Is this some LLVM specific problem or something? I don't think this is something Rust is inheriting from the C standard.

Copy link
Contributor

Choose a reason for hiding this comment

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

cc @rust-lang/lang @rust-lang/wg-unsafe-code-guidelines

Note that slices point to their entire range, so it is important that the length metadata is never too large. In particular, allocations and therefore slices cannot be bigger than isize::MAX bytes.

The total size of the slice must be no larger than isize::MAX bytes in memory. See the safety documentation of pointer::offset.

(Assuming these statements are normative.)

Copy link
Contributor

Choose a reason for hiding this comment

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

The first mentions allocations (does that mean heap allocations?),

I think it refers to any sort of allocation, including stack allocations (as your array example indicates).

and the second one seems specific to alloc.

That's a mistake on my part, it is defined in core as well.


So working on the assumption that this is unspecified / may become implementation-defined it seems to me that we have two choices:

  1. Use .wrapping_add(...) -- potentially a foot-gun if you use .contains tho not going to happen for real programs because of LLVM limitations and because of the sheer size of the allocation.

  2. Use assert!(...) as above. I'm not sure if LLVM would see the assertion and reason that it must always hold and so optimize it away.

We can probably switch between the two behaviors even after stabilizing because they are so pathological. However, it seems to me we should add a note to the documentation as well as the tracking issue and then the libs team can pick between one of them.


Changed it back to unsafe { add }, with a comment describing why it should be safe.

Haha; Seems we had the opposite take-aways.

Copy link
Member Author

@m-ou-se m-ou-se Oct 25, 2019

Choose a reason for hiding this comment

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

Ah, the Index implementation of slices assumes the same thing: https://doc.rust-lang.org/nightly/src/core/slice/mod.rs.html#2678-2724

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't want to wade into the issue of what's normative, but ptr.offset and related methods with restrictions to isize::MAX bytes are used pervasively from practically all safe slice APIs (at least, anything that ever accesses or takes the address of a slice element). Therefore:

  • it is impossible in practice to have a safe slice (in the sense that you can do safe operations on it and rest assures they won't cause UB) that spans more than isize::MAX bytes
  • we would have to audit and change a whole bunch of code throughout the standard library (or remove the isize::MAX restriction from offset and friends) if we ever wanted to support larger slices

So I think the current implementation (unsafe { add } with comment) is perfectly fine.´

I would advise against wrapping_add because it can cause performance degradation in some situations and there's no reason to risk that.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah that seems like a good conclusion. Let's keep the PR as-is.

@m-ou-se Could you add a note to the second bullet re. this not being normative (at least not yet) as well as link to rust-lang/unsafe-code-guidelines#102 (comment). With that I think we should be good to merge the PR.

(Also let's keep this thread visible since it was an interesting conversation.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

@m-ou-se m-ou-se force-pushed the slice-ptr-range branch 2 times, most recently from ca19770 to 29ef4b8 Compare October 25, 2019 13:33
@Centril
Copy link
Contributor

Centril commented Oct 25, 2019

Excellent all around; thanks!

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Oct 25, 2019

📌 Commit de9b660 has been approved by Centril

@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 Oct 25, 2019
Centril added a commit to Centril/rust that referenced this pull request Oct 25, 2019
…range, r=Centril

Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().

Implementation of rust-lang/rfcs#2791
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed (pretty log, 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.
2019-10-25T13:47:39.8867133Z ##[command]git remote add origin https://github.com/rust-lang/rust
2019-10-25T13:47:39.9094544Z ##[command]git config gc.auto 0
2019-10-25T13:47:39.9195152Z ##[command]git config --get-all http.https://github.com/rust-lang/rust.extraheader
2019-10-25T13:47:39.9257385Z ##[command]git config --get-all http.proxy
2019-10-25T13:47:39.9409524Z ##[command]git -c http.extraheader="AUTHORIZATION: basic ***" fetch --force --tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/*:refs/remotes/origin/* +refs/pull/65806/merge:refs/remotes/pull/65806/merge
---
2019-10-25T14:48:21.7596021Z .................................................................................................... 1600/9249
2019-10-25T14:48:27.4184478Z .................................................................................................... 1700/9249
2019-10-25T14:48:40.1280328Z ........................................................i...............i........................... 1800/9249
2019-10-25T14:48:47.7249940Z .................................................................................................... 1900/9249
2019-10-25T14:49:02.6189341Z ..............................................iiiii................................................. 2000/9249
2019-10-25T14:49:13.6182320Z .................................................................................................... 2200/9249
2019-10-25T14:49:16.2513138Z .................................................................................................... 2300/9249
2019-10-25T14:49:20.1851314Z .................................................................................................... 2400/9249
2019-10-25T14:49:43.5673131Z .................................................................................................... 2500/9249
---
2019-10-25T14:52:36.6710981Z ..................................................i...............i................................. 4800/9249
2019-10-25T14:52:45.6371868Z .................................................................................................... 4900/9249
2019-10-25T14:52:54.5216150Z .................................................................................................... 5000/9249
2019-10-25T14:53:00.7604355Z .................................................................................................... 5100/9249
2019-10-25T14:53:11.1171361Z ...................................................ii.ii............................................ 5200/9249
2019-10-25T14:53:21.0961838Z .................................................................................................... 5400/9249
2019-10-25T14:53:30.4285521Z .................................................................................................... 5500/9249
2019-10-25T14:53:38.2814389Z ..................i................................................................................. 5600/9249
2019-10-25T14:53:43.8473499Z .................................................................................................... 5700/9249
2019-10-25T14:53:43.8473499Z .................................................................................................... 5700/9249
2019-10-25T14:53:56.0158789Z .................................................................................................... 5800/9249
2019-10-25T14:54:07.4945729Z ...............ii...i..ii...........i............................................................... 5900/9249
2019-10-25T14:54:28.9611076Z .................................................................................................... 6100/9249
2019-10-25T14:54:37.1077859Z .................................................................................................... 6200/9249
2019-10-25T14:54:37.1077859Z .................................................................................................... 6200/9249
2019-10-25T14:54:50.0750137Z ......................................i..ii......................................................... 6300/9249
2019-10-25T14:55:12.1687906Z .................................................................................................... 6500/9249
2019-10-25T14:55:14.3970505Z ....i............................................................................................... 6600/9249
2019-10-25T14:55:16.7115602Z ...............................................................................i.................... 6700/9249
2019-10-25T14:55:19.4130670Z .................................................................................................... 6800/9249
---
2019-10-25T14:59:53.0870399Z  finished in 5.745
2019-10-25T14:59:53.1075586Z Check compiletest suite=codegen mode=codegen (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-10-25T14:59:53.2705322Z 
2019-10-25T14:59:53.2706185Z running 153 tests
2019-10-25T14:59:56.4299189Z i....iii......iii..iiii...i..............................i.i..................i....i...........ii.i. 100/153
2019-10-25T14:59:58.3916426Z i..iiii..............i.........iii.i.........ii......
2019-10-25T14:59:58.3920946Z 
2019-10-25T14:59:58.3924711Z  finished in 5.285
2019-10-25T14:59:58.4134157Z Check compiletest suite=codegen-units mode=codegen-units (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-10-25T14:59:58.9923297Z 
---
2019-10-25T15:00:00.5743965Z  finished in 2.161
2019-10-25T15:00:00.5940256Z Check compiletest suite=assembly mode=assembly (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-10-25T15:00:00.7606393Z 
2019-10-25T15:00:00.7607066Z running 9 tests
2019-10-25T15:00:00.7608437Z iiiiiiiii
2019-10-25T15:00:00.7609333Z 
2019-10-25T15:00:00.7614123Z  finished in 0.167
2019-10-25T15:00:00.7796914Z Check compiletest suite=incremental mode=incremental (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-10-25T15:00:00.9421578Z 
---
2019-10-25T15:00:19.0801904Z  finished in 18.300
2019-10-25T15:00:19.0998068Z Check compiletest suite=debuginfo mode=debuginfo-gdb+lldb (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-10-25T15:00:19.2630740Z 
2019-10-25T15:00:19.2632102Z running 123 tests
2019-10-25T15:00:44.2664673Z .iiiii...i.....i..i...i..i.i.i..i.ii..i.i.....i..i....ii..........iiii..........i...ii...i.......ii. 100/123
2019-10-25T15:00:49.1032614Z i.i.i......iii.i.....ii
2019-10-25T15:00:49.1033196Z 
2019-10-25T15:00:49.1037876Z  finished in 30.004
2019-10-25T15:00:49.1048169Z Uplifting stage1 rustc (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-10-25T15:00:49.1048874Z Copying stage2 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
---
2019-10-25T15:13:29.8916200Z 
2019-10-25T15:13:29.8926151Z    Doc-tests core
2019-10-25T15:13:35.2050924Z 
2019-10-25T15:13:35.2052163Z running 2408 tests
2019-10-25T15:13:46.4422331Z ......iiiii......................................................................................... 100/2408
2019-10-25T15:13:57.4160001Z ................................................................................ii.................. 200/2408
2019-10-25T15:14:23.2137488Z ..i................................................................................................. 400/2408
2019-10-25T15:14:23.2137488Z ..i................................................................................................. 400/2408
2019-10-25T15:14:33.8508440Z .................................................i..i.................iiii.......................... 500/2408
2019-10-25T15:14:54.5278550Z .................................................................................................... 700/2408
2019-10-25T15:15:05.0778128Z .................................................................................................... 800/2408
2019-10-25T15:15:15.6190034Z .................................................................................................... 900/2408
2019-10-25T15:15:26.3508807Z .................................................................................................... 1000/2408
---
2019-10-25T15:18:03.6749123Z ---- slice/mod.rs - slice::[T]::as_ptr_range (line 428) stdout ----
2019-10-25T15:18:03.6749449Z error[E0658]: use of unstable library feature 'slice_ptr_range'
2019-10-25T15:18:03.6749703Z  --> slice/mod.rs:432:11
2019-10-25T15:18:03.6749777Z   |
2019-10-25T15:18:03.6749828Z 7 | assert!(a.as_ptr_range().contains(x));
2019-10-25T15:18:03.6749924Z   |
2019-10-25T15:18:03.6749924Z   |
2019-10-25T15:18:03.6750405Z   = note: for more information, see ***/issues/65807
2019-10-25T15:18:03.6750480Z   = help: add `#![feature(slice_ptr_range)]` to the crate attributes to enable
2019-10-25T15:18:03.6750631Z error[E0308]: mismatched types
2019-10-25T15:18:03.6750961Z  --> slice/mod.rs:432:35
2019-10-25T15:18:03.6751018Z   |
2019-10-25T15:18:03.6751018Z   |
2019-10-25T15:18:03.6751089Z 7 | assert!(a.as_ptr_range().contains(x));
2019-10-25T15:18:03.6751418Z   |                                   ^ expected *-ptr, found integer
2019-10-25T15:18:03.6751476Z   |
2019-10-25T15:18:03.6751528Z   = note: expected type `&*const {integer}`
2019-10-25T15:18:03.6751602Z              found type `&{integer}`
2019-10-25T15:18:03.6751951Z error[E0658]: use of unstable library feature 'slice_ptr_range'
2019-10-25T15:18:03.6752238Z  --> slice/mod.rs:433:12
2019-10-25T15:18:03.6752294Z   |
2019-10-25T15:18:03.6752294Z   |
2019-10-25T15:18:03.6752345Z 8 | assert!(!a.as_ptr_range().contains(y));
2019-10-25T15:18:03.6752461Z   |
2019-10-25T15:18:03.6752461Z   |
2019-10-25T15:18:03.6752827Z   = note: for more information, see ***/issues/65807
2019-10-25T15:18:03.6752915Z   = help: add `#![feature(slice_ptr_range)]` to the crate attributes to enable
2019-10-25T15:18:03.6753023Z error[E0308]: mismatched types
2019-10-25T15:18:03.6753309Z  --> slice/mod.rs:433:36
2019-10-25T15:18:03.6753382Z   |
2019-10-25T15:18:03.6753382Z   |
2019-10-25T15:18:03.6753433Z 8 | assert!(!a.as_ptr_range().contains(y));
2019-10-25T15:18:03.6754217Z   |                                    ^ expected *-ptr, found integer
2019-10-25T15:18:03.6754310Z   |
2019-10-25T15:18:03.6754359Z   = note: expected type `&*const {integer}`
2019-10-25T15:18:03.6754410Z              found type `&{integer}`
2019-10-25T15:18:03.6754676Z error: aborting due to 4 previous errors
2019-10-25T15:18:03.6754714Z 
2019-10-25T15:18:03.6754766Z Some errors have detailed explanations: E0308, E0658.
2019-10-25T15:18:03.6755107Z For more information about an error, try `rustc --explain E0308`.
---
2019-10-25T15:18:03.6755917Z 
2019-10-25T15:18:03.6777827Z error: test failed, to rerun pass '--doc'
2019-10-25T15:18:03.6784916Z 
2019-10-25T15:18:03.6785158Z 
2019-10-25T15:18:03.6786316Z command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "test" "-Zconfig-profile" "--target" "x86_64-unknown-linux-gnu" "-Zbinary-dep-depinfo" "-j" "2" "--release" "--locked" "--color" "always" "--features" "panic-unwind backtrace compiler-builtins-c" "--manifest-path" "/checkout/src/libtest/Cargo.toml" "-p" "core" "--" "--quiet"
2019-10-25T15:18:03.6786510Z 
2019-10-25T15:18:03.6786545Z 
2019-10-25T15:18:03.6801416Z failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
2019-10-25T15:18:03.6801789Z Build completed unsuccessfully in 1:23:34
2019-10-25T15:18:03.6801789Z Build completed unsuccessfully in 1:23:34
2019-10-25T15:18:03.6856044Z == clock drift check ==
2019-10-25T15:18:03.6874351Z   local time: Fri Oct 25 15:18:03 UTC 2019
2019-10-25T15:18:03.9783230Z   network time: Fri, 25 Oct 2019 15:18:03 GMT
2019-10-25T15:18:03.9786817Z == end clock drift check ==
2019-10-25T15:18:04.5042177Z 
2019-10-25T15:18:04.5185162Z ##[error]Bash exited with code '1'.
2019-10-25T15:18:04.5223573Z ##[section]Starting: Checkout
2019-10-25T15:18:04.5225936Z ==============================================================================
2019-10-25T15:18:04.5226022Z Task         : Get sources
2019-10-25T15:18:04.5226076Z Description  : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.

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 Oct 25, 2019

Ah bummer; my bad! -- I forgot the feature gate in the doctests; you'll need to add those.

@bors r- (and r=me again with the gates added to the top of the doc-tests)

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Oct 25, 2019
@m-ou-se m-ou-se requested a review from Centril October 25, 2019 15:24
@m-ou-se
Copy link
Member Author

m-ou-se commented Oct 25, 2019

Oh whoops. I forgot to run the doc tests. Fixed now.

@bors r=@Centril

@bors
Copy link
Contributor

bors commented Oct 25, 2019

@m-ou-se: 🔑 Insufficient privileges: Not in reviewers

@Centril
Copy link
Contributor

Centril commented Oct 25, 2019

@bors r+

@bors
Copy link
Contributor

bors commented Oct 25, 2019

📌 Commit 225b245 has been approved by Centril

@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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 25, 2019
Centril added a commit to Centril/rust that referenced this pull request Oct 25, 2019
…range, r=Centril

Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().

Implementation of rust-lang/rfcs#2791
@m-ou-se
Copy link
Member Author

m-ou-se commented Oct 25, 2019

Ugh, looks like it was still broken. I'm still getting used to ./x.py. Sorry for the noise.

Is there any way to make ./x.py run only the doctests, without it completely rebuilding rustc and std etc.?

@Centril
Copy link
Contributor

Centril commented Oct 25, 2019

Not that I'm aware of; but cc @GuillaumeGomez

@bors r+

@bors
Copy link
Contributor

bors commented Oct 25, 2019

📌 Commit 381c442 has been approved by Centril

Centril added a commit to Centril/rust that referenced this pull request Oct 25, 2019
…range, r=Centril

Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().

Implementation of rust-lang/rfcs#2791
bors added a commit that referenced this pull request Oct 25, 2019
Rollup of 7 pull requests

Successful merges:

 - #63810 (Make <*const/mut T>::offset_from `const fn`)
 - #65705 (Add {String,Vec}::into_raw_parts)
 - #65749 (Insurance policy in case `iter.size_hint()` lies.)
 - #65799 (Fill tracking issue number for `array_value_iter`)
 - #65800 (self-profiling: Update measureme to 0.4.0 and remove non-RAII methods from profiler.)
 - #65806 (Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().)
 - #65810 (SGX: Clear additional flag on enclave entry)

Failed merges:

r? @ghost
JohnTitor added a commit to JohnTitor/rust that referenced this pull request Oct 25, 2019
…range, r=Centril

Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().

Implementation of rust-lang/rfcs#2791
@RalfJung
Copy link
Member

Is there any way to make ./x.py run only the doctests, without it completely rebuilding rustc and std etc.?

If you are only changing libstd and not the compiler, I think ./x.py test --stage 0 --doc src/libcore should do it.

bors added a commit that referenced this pull request Oct 25, 2019
Rollup of 6 pull requests

Successful merges:

 - #65705 (Add {String,Vec}::into_raw_parts)
 - #65749 (Insurance policy in case `iter.size_hint()` lies.)
 - #65799 (Fill tracking issue number for `array_value_iter`)
 - #65800 (self-profiling: Update measureme to 0.4.0 and remove non-RAII methods from profiler.)
 - #65806 (Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().)
 - #65810 (SGX: Clear additional flag on enclave entry)

Failed merges:

r? @ghost
@GuillaumeGomez
Copy link
Member

Is there any way to make ./x.py run only the doctests, without it completely rebuilding rustc and std etc.?

To run doctests, you need the std to be built as far as I know. So unfortunately, I'd say no. :-/

If you are only changing libstd and not the compiler, I think ./x.py test --stage 0 --doc src/libcore should do it.

Last time I tried some doc-related checks, you couldn't start them at stage 0. If that changed, it'll make me save a lot of time!

@bors bors merged commit 381c442 into rust-lang:master Oct 25, 2019
@RalfJung
Copy link
Member

Last time I tried some doc-related checks, you couldn't start them at stage 0. If that changed, it'll make me save a lot of time!

For me they work but give a weird error that one can seemingly ignore.

Even if they don't, you can save a lot of time on re-runs by doing --keep-stage 0 --stage 1. Then it won't rebuild rustc either. But keep-stage only works starting from the second build.

@m-ou-se m-ou-se deleted the slice-ptr-range branch October 27, 2019 13:20
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.

9 participants