-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
impl Index<RangeFrom> for CStr #74021
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
What's your use case for this method? I'm a bit hesitant to add this API because its performance is impacted by the theoretically-planned change from representing |
In any case, cc @rust-lang/libs because this would be insta-stable and hence needs an FCP. |
I think this is very useful functionality! @rfcbot fcp merge |
Team member @Amanieu has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
@hanna-kruppe Sorry for taking so long to reply. I don't have a use-case, just thought it'd be nice to have, since it's currently kinda difficult to get I see the desire to treat But tbh I'm not sure how I feel about that, since this breaks a couple of assumptions I have about references:
Say we have a C function that returns a For this feature, the only way I can think of that still allows for it without making the potential changes you mentioned more difficult is something like this: // assume `self` is the same as `*const c_char`
let len = sys::strlen(self);
if index.start < len {
self.offset(index.start)
} else {
// emulate an out-of-bounds panic
panic!("index out of bounds: the len is {} but the index is {}", len, index.start");
} But of course this means that it'll need to calculate the length every time to make sure it's not going over the end, rather than using a cached length. |
Frankly, I also have my doubts about the usefulness of that change at this point, but for different reasons. The way dynamically-sized types (DST) in Rust work, it's a bit sloppy to talk about And yet, generalized DSTs would still have a baked-in assumption that the size is rather cheap to fetch, which would not be true for "thin Still, despite my misgivings, the plan of record is to to make
Right, something like that. An improvement is possible when |
I think this is waiting on one other libs member to sign off in #74021 (comment) or to raise objections. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
@bors r+ |
📌 Commit 30b8835 has been approved by |
…arth Rollup of 7 pull requests Successful merges: - rust-lang#70817 (Add core::task::ready! macro) - rust-lang#73762 (Document the trait keyword) - rust-lang#74021 (impl Index<RangeFrom> for CStr) - rust-lang#74071 (rustc_metadata: Make crate loading fully speculative) - rust-lang#74445 (add test for rust-lang#62878) - rust-lang#74459 (Make unreachable_unchecked a const fn) - rust-lang#74478 (Revert "Use an UTF-8 locale for the linker.") Failed merges: r? @ghost
@rust-timer make-pr-for f305b20 |
Original message: Rollup merge of rust-lang#74021 - 1011X:master, r=dtolnay impl Index<RangeFrom> for CStr This change implements (partial) slicing for `CStr`. Since a `CStr` must end in a null byte, it's not possible to trim from the right and still have a valid `CStr`. But, it *is* possible to trim from the left. This lets us be a bit more flexible and treat them more like strings. ```rust let string = CStr::from_bytes_with_nul(b"Hello World!\0"); let result = CStr::from_bytes_with_nul(b"World!\0"); assert_eq!(&string[6..], result); ```
@rust-lang/libs Did we consider the impact of this change on the possible future implementation of choice of not caching the length of the C string, as mentioned by @hanna-kruppe above? In particular, with this API stabilized, I feel it is very unlikely that we would ever stop caching the length. Note that this is about to be on the stable release in a couple days. |
I considered it. I don't think this is incompatible with using a ptr-only representation for &CStr. Indexing with |
@dtolnay Interesting. I think that would be our first impl of |
BTreeMap Index is log n, at least, though that's "better" than n |
Release is tomorrow, we can back the stabilization out for a release if that gives y'all more time to think. |
cc @rust-lang/libs Does anyone want to second reconsidering this? If it's just me then happy to let it rest. We should at least carefully document this. Because it's going to be a potentially surprising performance footgun if we ever do decide to stop caching the length. |
I also feel a bit uneasy. |
Pkgsrc changes: * Remove patches now integrated upstream, many related to SunOS / Illumos. * The LLVM fix for powerpc is also now integrated upstream. * Adapt those patches where the source has moved or parts are integrated. * The randomness patches no longer applies, and I could not find where those files went... * Provide a separate bootstrap for NetBSD/powerpc 9.0, since apparently the C++ ABI is different from 8.0. Yes, this appears to be specific to the NetBSD powerpc ports. Upstream changes: Version 1.47.0 (2020-10-08) ========================== Language -------- - [Closures will now warn when not used.][74869] Compiler -------- - [Stabilized the `-C control-flow-guard` codegen option][73893], which enables [Control Flow Guard][1.47.0-cfg] for Windows platforms, and is ignored on other platforms. - [Upgraded to LLVM 11.][73526] - [Added tier 3\* support for the `thumbv4t-none-eabi` target.][74419] - [Upgrade the FreeBSD toolchain to version 11.4][75204] - [`RUST_BACKTRACE`'s output is now more compact.][75048] \* Refer to Rust's [platform support page][forge-platform-support] for more information on Rust's tiered platform support. Libraries --------- - [`CStr` now implements `Index<RangeFrom<usize>>`.][74021] - [Traits in `std`/`core` are now implemented for arrays of any length, not just those of length less than 33.][74060] - [`ops::RangeFull` and `ops::Range` now implement Default.][73197] - [`panic::Location` now implements `Copy`, `Clone`, `Eq`, `Hash`, `Ord`, `PartialEq`, and `PartialOrd`.][73583] Stabilized APIs --------------- - [`Ident::new_raw`] - [`Range::is_empty`] - [`RangeInclusive::is_empty`] - [`Result::as_deref`] - [`Result::as_deref_mut`] - [`Vec::leak`] - [`pointer::offset_from`] - [`f32::TAU`] - [`f64::TAU`] The following previously stable APIs have now been made const. - [The `new` method for all `NonZero` integers.][73858] - [The `checked_add`,`checked_sub`,`checked_mul`,`checked_neg`, `checked_shl`, `checked_shr`, `saturating_add`, `saturating_sub`, and `saturating_mul` methods for all integers.][73858] - [The `checked_abs`, `saturating_abs`, `saturating_neg`, and `signum` for all signed integers.][73858] - [The `is_ascii_alphabetic`, `is_ascii_uppercase`, `is_ascii_lowercase`, `is_ascii_alphanumeric`, `is_ascii_digit`, `is_ascii_hexdigit`, `is_ascii_punctuation`, `is_ascii_graphic`, `is_ascii_whitespace`, and `is_ascii_control` methods for `char` and `u8`.][73858] Cargo ----- - [`build-dependencies` are now built with opt-level 0 by default.][cargo/8500] You can override this by setting the following in your `Cargo.toml`. ```toml [profile.release.build-override] opt-level = 3 ``` - [`cargo-help` will now display man pages for commands rather just the `--help` text.][cargo/8456] - [`cargo-metadata` now emits a `test` field indicating if a target has tests enabled.][cargo/8478] - [`workspace.default-members` now respects `workspace.exclude`.][cargo/8485] - [`cargo-publish` will now use an alternative registry by default if it's the only registry specified in `package.publish`.][cargo/8571] Misc ---- - [Added a help button beside Rustdoc's searchbar that explains rustdoc's type based search.][75366] - [Added the Ayu theme to rustdoc.][71237] Compatibility Notes ------------------- - [Bumped the minimum supported Emscripten version to 1.39.20.][75716] - [Fixed a regression parsing `{} && false` in tail expressions.][74650] - [Added changes to how proc-macros are expanded in `macro_rules!` that should help to preserve more span information.][73084] These changes may cause compiliation errors if your macro was unhygenic or didn't correctly handle `Delimiter::None`. - [Moved support for the CloudABI target to tier 3.][75568] - [`linux-gnu` targets now require minimum kernel 2.6.32 and glibc 2.11.][74163] Internal Only -------- - [Improved default settings for bootstrapping in `x.py`.][73964] You can read details about this change in the ["Changes to `x.py` defaults"](https://blog.rust-lang.org/inside-rust/2020/08/30/changes-to-x-py-defaults.html) post on the Inside Rust blog. - [Added the `rustc-docs` component.][75560] This allows you to install and read the documentation for the compiler internal APIs. (Currently only available for `x86_64-unknown-linux-gnu`.) [1.47.0-cfg]: https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard [76980]: rust-lang/rust#76980 [75048]: rust-lang/rust#75048 [74163]: rust-lang/rust#74163 [71237]: rust-lang/rust#71237 [74869]: rust-lang/rust#74869 [73858]: rust-lang/rust#73858 [75716]: rust-lang/rust#75716 [75908]: rust-lang/rust#75908 [75516]: rust-lang/rust#75516 [75560]: rust-lang/rust#75560 [75568]: rust-lang/rust#75568 [75366]: rust-lang/rust#75366 [75204]: rust-lang/rust#75204 [74650]: rust-lang/rust#74650 [74419]: rust-lang/rust#74419 [73964]: rust-lang/rust#73964 [74021]: rust-lang/rust#74021 [74060]: rust-lang/rust#74060 [73893]: rust-lang/rust#73893 [73526]: rust-lang/rust#73526 [73583]: rust-lang/rust#73583 [73084]: rust-lang/rust#73084 [73197]: rust-lang/rust#73197 [72488]: rust-lang/rust#72488 [cargo/8456]: rust-lang/cargo#8456 [cargo/8478]: rust-lang/cargo#8478 [cargo/8485]: rust-lang/cargo#8485 [cargo/8500]: rust-lang/cargo#8500 [cargo/8571]: rust-lang/cargo#8571 [`Ident::new_raw`]: https://doc.rust-lang.org/nightly/proc_macro/struct.Ident.html#method.new_raw [`Range::is_empty`]: https://doc.rust-lang.org/nightly/std/ops/struct.Range.html#method.is_empty [`RangeInclusive::is_empty`]: https://doc.rust-lang.org/nightly/std/ops/struct.RangeInclusive.html#method.is_empty [`Result::as_deref_mut`]: https://doc.rust-lang.org/nightly/std/result/enum.Result.html#method.as_deref_mut [`Result::as_deref`]: https://doc.rust-lang.org/nightly/std/result/enum.Result.html#method.as_deref [`TypeId::of`]: https://doc.rust-lang.org/nightly/std/any/struct.TypeId.html#method.of [`Vec::leak`]: https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.leak [`f32::TAU`]: https://doc.rust-lang.org/nightly/std/f32/consts/constant.TAU.html [`f64::TAU`]: https://doc.rust-lang.org/nightly/std/f64/consts/constant.TAU.html [`pointer::offset_from`]: https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from
This change implements (partial) slicing for
CStr
.Since a
CStr
must end in a null byte, it's not possible to trim from the right and still have a validCStr
. But, it is possible to trim from the left. This lets us be a bit more flexible and treat them more like strings.