Avoid unreachable integer underflow check in CStr::count_bytes() - #163005
Conversation
|
rustbot has assigned @Mark-Simulacrum. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
This looks sound, but can you say a bit about what the benefit is? In #162912 you mentioned "A colleague of mine was trying to remove all panics in a Linux kernel driver" -- is this also intended to help eliminate an overflow check? I'm asking both because we should have something more reason than "we can" for using unsafe and because we should have a codegen test capturing that reason (or at least a reasonable proxy for it). |
This comment was marked as resolved.
This comment was marked as resolved.
|
FWIW, the technically-valid functionality of NonZero - 1 is something I've used a lot and have wanted to add a dedicated method for. But in this case it wouldn't help since we're dealing with slice lengths. |
|
This is not some random function. I do in general think it's worth it for core vocabulary types such as I suppose there is a safe implementation: self.to_bytes().len()Of course since |
CStr::count_bytes()CStr::count_bytes()
|
Well, the codegen test is a good call. Interestingly enough, neither computing the length Of course the |
I am sympathetic to this, as long as it doesn't impose undue maintenance burden. But for overflow checks in particular, I'm a bit skeptical because we don't ship the standard library with overflow checks enabled. It's possible to build the standard library like this (and maybe it'll become more common as build-std matures), but today it's a rare configuration that is rarely benchmarked and rarely optimized for. I guess this PR and earlier ones are evidence that this is starting to change, but today there's probably many other places that have overflow checks. So if this is going to lead to a steady stream of PRs to find and eliminate such overflow checks, that seems like a bigger change that we should have a discussion in the libs team about at some point (e.g., how much do we care about this vs. maintainability, how do we catch regressions and prioritize them, should we have tests and CI jobs that exercise this directly, etc.). |
|
Huh. I had not realized that he ran into this overflow check due to how Linux builds core. I thought this was how it worked for everyone. Back when I was working on the target modifiers RFC, it was explained to me that the stdlib has a way to inherit overflow checks, and that this is why |
|
Sorry for my sloppy phrasing, the standard library does have ways to inherit overflow checks, but they're opt-in and fairly targeted (see |
|
I opened a discussion about overflow checks on zulip: #t-libs > Future of overflow checks in the standard library @ 💬 |
| pub const fn count_bytes(&self) -> usize { | ||
| self.inner.len() - 1 | ||
| // SAFETY: This length includes the nul-terminator, so it's at least one. | ||
| unsafe { self.inner.len().unchecked_sub(1) } |
There was a problem hiding this comment.
I think I'm OK with this. An alternative could be to try to_bytes().len(), which technically should/could avoid the panic (to_bytes_with_nul, which it calls, has an assert_unchecked(!empty)).
But the added indirection doesn't seem like it has a ton of value and probably hurts optimization (at least in terms of how long it takes to compile).
There was a problem hiding this comment.
assert_unchecked does actually hurt a lot more than it helps, so, the unchecked sub should just help convey the length information properly, honestly.
…Simulacrum Avoid unreachable integer underflow check in `CStr::count_bytes()` Follow up to rust-lang#162930. cc @clarfonthey, @hanna-kruppe
Rollup of 15 pull requests Successful merges: - #161051 (When error from local macro, include macro def span) - #162750 (add case mapping fast paths for Latin-1) - #162831 (Do not continue past `rustc_resolve` when encountering duplicated items) - #162835 (rustdoc: account for nested parens and split text events in bare urls lint) - #163044 (Report runtime range endpoints for runtime values) - #163062 (Use x30 register name with LLVM 23+) - #158102 (When compiling without a specified `--edition`, emit a note) - #162984 (Windows: don't error if `access_mode` is set on `OpenOptions`) - #163005 (Avoid unreachable integer underflow check in `CStr::count_bytes()`) - #163019 (Prepare for the introduction of forced keywords (`k#`)) - #163020 (Dir: fix fallback impl for remove_dir) - #163047 (Use verbose suggestion for `mut binding` instead of `&mut binding`) - #163075 (Fix ArgAttributes mismatches in ABI UI tests for LoongArch64 and RiscV64) - #163079 (enable `f128` from `u64`/`i64` test) - #163082 (Remove `TypeChecker::root_cx`)
…Simulacrum Avoid unreachable integer underflow check in `CStr::count_bytes()` Follow up to rust-lang#162930. cc @clarfonthey, @hanna-kruppe
…uwer Rollup of 18 pull requests Successful merges: - #161051 (When error from local macro, include macro def span) - #161629 (Streamline `StateDiffCollector`) - #162750 (add case mapping fast paths for Latin-1) - #162831 (Do not continue past `rustc_resolve` when encountering duplicated items) - #162835 (rustdoc: account for nested parens and split text events in bare urls lint) - #162952 (Depend on lockfiles to prevent GC of the current session) - #163044 (Report runtime range endpoints for runtime values) - #163062 (Use x30 register name with LLVM 23+) - #158102 (When compiling without a specified `--edition`, emit a note) - #162939 (Declare multi-kind constants for MacroKinds) - #162984 (Windows: don't error if `access_mode` is set on `OpenOptions`) - #163005 (Avoid unreachable integer underflow check in `CStr::count_bytes()`) - #163019 (Prepare for the introduction of forced keywords (`k#`)) - #163020 (Dir: fix fallback impl for remove_dir) - #163047 (Use verbose suggestion for `mut binding` instead of `&mut binding`) - #163075 (Fix ArgAttributes mismatches in ABI UI tests for LoongArch64 and RiscV64) - #163079 (enable `f128` from `u64`/`i64` test) - #163082 (Remove `TypeChecker::root_cx`)
…uwer Rollup of 19 pull requests Successful merges: - #161051 (When error from local macro, include macro def span) - #161629 (Streamline `StateDiffCollector`) - #162750 (add case mapping fast paths for Latin-1) - #162831 (Do not continue past `rustc_resolve` when encountering duplicated items) - #162835 (rustdoc: account for nested parens and split text events in bare urls lint) - #162952 (Depend on lockfiles to prevent GC of the current session) - #163044 (Report runtime range endpoints for runtime values) - #163062 (Use x30 register name with LLVM 23+) - #163091 (miri subtree update) - #162939 (Declare multi-kind constants for MacroKinds) - #162984 (Windows: don't error if `access_mode` is set on `OpenOptions`) - #163005 (Avoid unreachable integer underflow check in `CStr::count_bytes()`) - #163019 (Prepare for the introduction of forced keywords (`k#`)) - #163020 (Dir: fix fallback impl for remove_dir) - #163041 (Be more explicit on suggestion type without changing how they are rendered) - #163047 (Use verbose suggestion for `mut binding` instead of `&mut binding`) - #163075 (Fix ArgAttributes mismatches in ABI UI tests for LoongArch64 and RiscV64) - #163079 (enable `f128` from `u64`/`i64` test) - #163082 (Remove `TypeChecker::root_cx`)
Rollup merge of #163005 - Darksonn:cstr-count-bytes, r=Mark-Simulacrum Avoid unreachable integer underflow check in `CStr::count_bytes()` Follow up to #162930. cc @clarfonthey, @hanna-kruppe
…uwer Rollup of 19 pull requests Successful merges: - rust-lang/rust#161051 (When error from local macro, include macro def span) - rust-lang/rust#161629 (Streamline `StateDiffCollector`) - rust-lang/rust#162750 (add case mapping fast paths for Latin-1) - rust-lang/rust#162831 (Do not continue past `rustc_resolve` when encountering duplicated items) - rust-lang/rust#162835 (rustdoc: account for nested parens and split text events in bare urls lint) - rust-lang/rust#162952 (Depend on lockfiles to prevent GC of the current session) - rust-lang/rust#163044 (Report runtime range endpoints for runtime values) - rust-lang/rust#163062 (Use x30 register name with LLVM 23+) - rust-lang/rust#163091 (miri subtree update) - rust-lang/rust#162939 (Declare multi-kind constants for MacroKinds) - rust-lang/rust#162984 (Windows: don't error if `access_mode` is set on `OpenOptions`) - rust-lang/rust#163005 (Avoid unreachable integer underflow check in `CStr::count_bytes()`) - rust-lang/rust#163019 (Prepare for the introduction of forced keywords (`k#`)) - rust-lang/rust#163020 (Dir: fix fallback impl for remove_dir) - rust-lang/rust#163041 (Be more explicit on suggestion type without changing how they are rendered) - rust-lang/rust#163047 (Use verbose suggestion for `mut binding` instead of `&mut binding`) - rust-lang/rust#163075 (Fix ArgAttributes mismatches in ABI UI tests for LoongArch64 and RiscV64) - rust-lang/rust#163079 (enable `f128` from `u64`/`i64` test) - rust-lang/rust#163082 (Remove `TypeChecker::root_cx`)
Follow up to #162930.
cc @clarfonthey, @hanna-kruppe