Rework smallest_range_containing to handle duplicates - #160198
Conversation
|
r? @nnethercote rustbot has assigned @nnethercote. Use Why was this reviewer chosen?The reviewer was selected based on:
|
There was a problem hiding this comment.
The new code makes sense. Some observations from someone who doesn't know anything about enum representation stuff...
WrappingRangeis a really weird type.smallest_range_containingis a really weird operation on a really weird type.- The docs for
smallest_range_containingcontain only one case where theWrappingRangeactually wraps, which seems low because that's trickier than the non-wrapping case.
|
r=me if you want it, after considering the comment above. |
28f46eb to
5b9efe2
Compare
|
Thanks, that note about testing is a good one. I stopped cramming everything into the doc comment and made some Since I didn't change the implementation itself from what was previously reviewed, though, |
…ining, r=nnethercote Rework `smallest_range_containing` to handle duplicates @theemathas [pointed out](rust-lang#159438 (comment)) that this method I added in rust-lang#159509 is implicitly assuming that there are no duplicates in the input. That's not a problem for its one use today -- an enum whose layout matters can't have duplicate discriminants -- but it could be a sharp edge in future, so this PR reworks it to handle duplicate values fine. As a bonus, as I tried a couple different approaches (from just asserting to deduping to more) I found this rephrasing that I think is clearer. In particular, while the `.iter().copied().cycle().skip(1)` I'd written *works*, it's definitely not something that you look at and think "oh, obviously". I think this version using `.array_windows::<2>()` is easier to follow and splitting the wraparound and non-wraparound cases also simplifies the `min_by_key` lambda. No changes to any layouts from this -- it just refactors this function.
…uwer Rollup of 22 pull requests Successful merges: - #158147 (std: fix stack buffer overflow in Windows junction_point) - #159784 (Hint that memchr returns an in-bounds index) - #160130 (Select cache values to verify by key fingerprint, not value fingerprint) - #160343 (Rename `OutlivesPredicate` to `OutlivesClause`) - #160360 (Remove rustc_middle dependency on rustc_hir_pretty) - #160387 (rustc_codegen_ssa: Correctly apply the static `--jobs-backend` limit to backend parallelism) - #160422 (move mir-opt miri tests to CI logic) - #160444 (Avoid resolving path keywords outside `TypeNS`) - #160510 (Resolver: (un)tracked borrows for `CmRefCell` made safe my unsafe speculative flag) - #155424 ([blocked] Link to proposed LLM policy in CONTRIBUTING and pull request template) - #158726 (std: move futex implementations into sys::sync::futex) - #159225 (Split IncrCompSession out of Session) - #159820 (Make the `rustc_unsafe_specialization_marker` attribute actually `unsafe`) - #160198 (Rework `smallest_range_containing` to handle duplicates) - #160362 (Split `SpannedTypeVisitor` into its own crate, `rustc_ty_walk`) - #160390 (autodiff: Handle slice-tailed DSTs in type trees) - #160420 (Suggest `cast_signed()` for overflowing signed integer literals) - #160520 (Add some tests for specialization) - #160522 (fix(bootstrap): Normalize the names of proc macro dependency crates) - #160531 (docs: fix typo in AllowExprMetavar comment) - #160538 (Update expect messages in tcp.rs doc examples to follow the style guide) - #160548 (bootstrap: Register `coverage-map` and `coverage-run` aliases via a separate step)
…ining, r=nnethercote Rework `smallest_range_containing` to handle duplicates @theemathas [pointed out](rust-lang#159438 (comment)) that this method I added in rust-lang#159509 is implicitly assuming that there are no duplicates in the input. That's not a problem for its one use today -- an enum whose layout matters can't have duplicate discriminants -- but it could be a sharp edge in future, so this PR reworks it to handle duplicate values fine. As a bonus, as I tried a couple different approaches (from just asserting to deduping to more) I found this rephrasing that I think is clearer. In particular, while the `.iter().copied().cycle().skip(1)` I'd written *works*, it's definitely not something that you look at and think "oh, obviously". I think this version using `.array_windows::<2>()` is easier to follow and splitting the wraparound and non-wraparound cases also simplifies the `min_by_key` lambda. No changes to any layouts from this -- it just refactors this function.
…uwer Rollup of 25 pull requests Successful merges: - #154585 (treat no_mangle_generic_items as hard error instead of lint warning) - #158147 (std: fix stack buffer overflow in Windows junction_point) - #160130 (Select cache values to verify by key fingerprint, not value fingerprint) - #160343 (Rename `OutlivesPredicate` to `OutlivesClause`) - #160360 (Remove rustc_middle dependency on rustc_hir_pretty) - #160387 (rustc_codegen_ssa: Correctly apply the static `--jobs-backend` limit to backend parallelism) - #160422 (move mir-opt miri tests to CI logic) - #160444 (Avoid resolving path keywords outside `TypeNS`) - #160510 (Resolver: (un)tracked borrows for `CmRefCell` made safe my unsafe speculative flag) - #155424 ([blocked] Link to proposed LLM policy in CONTRIBUTING and pull request template) - #158726 (std: move futex implementations into sys::sync::futex) - #158762 (Emit thumb code on VEX V5) - #159225 (Split IncrCompSession out of Session) - #159820 (Make the `rustc_unsafe_specialization_marker` attribute actually `unsafe`) - #160198 (Rework `smallest_range_containing` to handle duplicates) - #160362 (Split `SpannedTypeVisitor` into its own crate, `rustc_ty_walk`) - #160390 (autodiff: Handle slice-tailed DSTs in type trees) - #160420 (Suggest `cast_signed()` for overflowing signed integer literals) - #160516 (Add regression test for HRTB projection in closure) - #160520 (Add some tests for specialization) - #160522 (fix(bootstrap): Normalize the names of proc macro dependency crates) - #160523 (Add regression test for opaque type) - #160531 (docs: fix typo in AllowExprMetavar comment) - #160538 (Update expect messages in tcp.rs doc examples to follow the style guide) - #160548 (bootstrap: Register `coverage-map` and `coverage-run` aliases via a separate step)
…uwer Rollup of 25 pull requests Successful merges: - #158147 (std: fix stack buffer overflow in Windows junction_point) - #160130 (Select cache values to verify by key fingerprint, not value fingerprint) - #160343 (Rename `OutlivesPredicate` to `OutlivesClause`) - #160360 (Remove rustc_middle dependency on rustc_hir_pretty) - #160387 (rustc_codegen_ssa: Correctly apply the static `--jobs-backend` limit to backend parallelism) - #160422 (move mir-opt miri tests to CI logic) - #160444 (Avoid resolving path keywords outside `TypeNS`) - #160510 (Resolver: (un)tracked borrows for `CmRefCell` made safe by unsafe speculative flag) - #155424 ([blocked] Link to proposed LLM policy in CONTRIBUTING and pull request template) - #158726 (std: move futex implementations into sys::sync::futex) - #158762 (Emit thumb code on VEX V5) - #159225 (Split IncrCompSession out of Session) - #159820 (Make the `rustc_unsafe_specialization_marker` attribute actually `unsafe`) - #160198 (Rework `smallest_range_containing` to handle duplicates) - #160362 (Split `SpannedTypeVisitor` into its own crate, `rustc_ty_walk`) - #160390 (autodiff: Handle slice-tailed DSTs in type trees) - #160420 (Suggest `cast_signed()` for overflowing signed integer literals) - #160501 (Add bootstrap CLI snapshot test for testing miri) - #160516 (Add regression test for HRTB projection in closure) - #160520 (Add some tests for specialization) - #160522 (fix(bootstrap): Normalize the names of proc macro dependency crates) - #160523 (Add regression test for opaque type) - #160531 (docs: fix typo in AllowExprMetavar comment) - #160538 (Update expect messages in tcp.rs doc examples to follow the style guide) - #160548 (bootstrap: Register `coverage-map` and `coverage-run` aliases via a separate step)
Rollup merge of #160198 - scottmcm:redo-smallest_range_containing, r=nnethercote Rework `smallest_range_containing` to handle duplicates @theemathas [pointed out](#159438 (comment)) that this method I added in #159509 is implicitly assuming that there are no duplicates in the input. That's not a problem for its one use today -- an enum whose layout matters can't have duplicate discriminants -- but it could be a sharp edge in future, so this PR reworks it to handle duplicate values fine. As a bonus, as I tried a couple different approaches (from just asserting to deduping to more) I found this rephrasing that I think is clearer. In particular, while the `.iter().copied().cycle().skip(1)` I'd written *works*, it's definitely not something that you look at and think "oh, obviously". I think this version using `.array_windows::<2>()` is easier to follow and splitting the wraparound and non-wraparound cases also simplifies the `min_by_key` lambda. No changes to any layouts from this -- it just refactors this function.
|
@rust-timer build df08f9f |
|
Queued df08f9f with parent 22950ab, future comparison URL. |
@theemathas pointed out that this method I added in #159509 is implicitly assuming that there are no duplicates in the input. That's not a problem for its one use today -- an enum whose layout matters can't have duplicate discriminants -- but it could be a sharp edge in future, so this PR reworks it to handle duplicate values fine.
As a bonus, as I tried a couple different approaches (from just asserting to deduping to more) I found this rephrasing that I think is clearer. In particular, while the
.iter().copied().cycle().skip(1)I'd written works, it's definitely not something that you look at and think "oh, obviously". I think this version using.array_windows::<2>()is easier to follow and splitting the wraparound and non-wraparound cases also simplifies themin_by_keylambda.No changes to any layouts from this -- it just refactors this function.