Skip to content

Document why Range*<&T> as RangeBounds<T> impls are not T: ?Sized, and give an alternative. #144167

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

Merged
merged 1 commit into from
Jul 29, 2025

Conversation

zachs18
Copy link
Contributor

@zachs18 zachs18 commented Jul 19, 2025

Range*<&T> as RangeBounds<T> impls have been tried to be relaxed to T: ?Sized at least twice:

I also was just about to make another PR to do it again until I ./x.py test library/alloc and rediscovered the type inference regression, then searched around and found the previous PRs. Hence this PR instead so hopefully that doesn't keep happening 😛.

These impls cannot be relaxed for two reasons:

  1. Type inference regressions: See @SimonSapin's explanation from a previous PR: Add ?Sized bounds to all the RangeBounds impls #61584 (comment)
  2. It's a breaking change: impl RangeBounds<MyUnsizedType> for std::ops::Range<&MyUnsizedType> is allowed after the coherence rebalance (playground link), and relaxing these impls would conflict with that downstream impl.

This PR adds doc-comments explaining that not having T: ?Sized is intentional1, and gives an explicit alternative: (Bound<&T>, Bound<&T>).

Technically, the impls for the unstable new std::range types could be relaxed, as they are still unstable so the change would not be breaking, but having them be different in this regard seems worse (and the non-iterable RangeTo/RangeToInclusive range types are shared between the "new" and "old" so cannot be changed anyway), and then the type inference regression would pop up in whatever edition the new range types stabilize in.

The "see <link> for discussion of those issues" is intentionally left as a non-doc comment just for whoever may try to relax these impls again in the future, but if it is preferred to have the link in the docs I can add that.

Closes #107196 (as wontfix)
CC #64027

Footnotes

  1. "intentional" is maybe a bit of strong wording, should it instead say something like "was stabilized without it and it would be breaking to change it now"?

@rustbot
Copy link
Collaborator

rustbot commented Jul 19, 2025

r? @tgross35

rustbot has assigned @tgross35.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jul 19, 2025
Comment on lines 1144 to 1149
/// This impl intentionally does not have `T: ?Sized` due to type inference issues.
// see https://github.com/rust-lang/rust/pull/61584 for discussion of those issues
///
/// If you need to use this impl where `T` is unsized,
/// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound],
/// e.g. replace `start..` with `(Bound::Included(start), Bound::Unbounded)`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Few small nits/thoughts:

  • I don't think the "due to type inference issues" part needs to be in public docs. That reasoning is a bit of an internal detail, I think it's fine to just make the whole first sentence a non-doc comment.
  • Maybe "impl" -> "implementation" for prose
  • e.g. -> i.e. probably works because it's showing a pattern rather than a specific example
  • Looks like the paragraph needs a rewrap (100 chars)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • Okay, I've made that part a non-doc comment, and made it not mention the reasoning, just link to it.
  • 👍
  • 👍
  • The longest of the added lines in the source is ~86 characters; do you mean the length in the rendered docs?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah sorry, yeah the length is fine but it just looks like it got some random/copy+paste wrapping (e.g. there's plenty of room for "consider using the RangeBounds" the next line up). Not going to block on that though, the rest lgtm.

Thanks for the updates!

…ntentionally not `T: ?Sized`, and document (publically) an alternative.
@zachs18 zachs18 force-pushed the rangebounds-not-unsized-reason branch from 972b7e9 to 477814a Compare July 23, 2025 20:39
@tgross35
Copy link
Contributor

@bors r+ rollup

@bors
Copy link
Collaborator

bors commented Jul 29, 2025

📌 Commit 477814a has been approved by tgross35

It is now in the queue for this repository.

@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 Jul 29, 2025
Zalathar added a commit to Zalathar/rust that referenced this pull request Jul 29, 2025
…ason, r=tgross35

Document why `Range*<&T> as RangeBounds<T>` impls are not `T: ?Sized`, and give an alternative.

`Range*<&T> as RangeBounds<T>` impls have been tried to be relaxed to `T: ?Sized` at least twice:

* rust-lang#61584
* rust-lang#64327

I also was just about to make another PR to do it again until I `./x.py test library/alloc` and rediscovered the type inference regression, then searched around and found the previous PRs. Hence this PR instead so hopefully that doesn't keep happening 😛.

These impls cannot be relaxed for two reasons:

1. Type inference regressions: See `@SimonSapin's` explanation from a previous PR: rust-lang#61584 (comment)
2. It's a breaking change: `impl RangeBounds<MyUnsizedType> for std::ops::Range<&MyUnsizedType>` is allowed after the coherence rebalance ([playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f704a6fe53bfc33e55b2fc246d895ec2)), and relaxing these impls would conflict with that downstream impl.

This PR adds doc-comments explaining that not having `T: ?Sized` is intentional[^1], and gives an explicit alternative: `(Bound<&T>, Bound<&T>)`.

Technically, the impls for the unstable new `std::range` types could be relaxed, as they are still unstable so the change would not be breaking, but having them be different in this regard seems worse (and the non-iterable `RangeTo/RangeToInclusive` range types are shared between the "new" and "old" so cannot be changed anyway), and then the type inference regression would pop up in whatever edition the new range types stabilize in.

The "see \<link\> for discussion of those issues" is intentionally left as a non-doc comment just for whoever may try to relax these impls again in the future, but if it is preferred to have the link in the docs I can add that.

Closes rust-lang#107196 (as wontfix)
CC rust-lang#64027

[^1]: "intentional" is maybe a bit of strong wording, should it instead say something like "was stabilized without it and it would be breaking to change it now"?
bors added a commit that referenced this pull request Jul 29, 2025
Rollup of 14 pull requests

Successful merges:

 - #144022 (Implementation: `#[feature(sync_nonpoison)]`, `#[feature(nonpoison_mutex)]`)
 - #144167 (Document why `Range*<&T> as RangeBounds<T>` impls are not `T: ?Sized`, and give an alternative.)
 - #144407 (fix(debuginfo): disable overflow check for recursive non-enum types)
 - #144451 (fix: Reject upvar scrutinees for `loop_match`)
 - #144482 (Add explicit download methods to download module in bootstrap)
 - #144500 (thread name in stack overflow message)
 - #144511 (tidy: increase performance of auto extra checks feature)
 - #144586 (Update wasi-sdk to 27.0 in CI)
 - #144599 (bootstrap: enable tidy auto extra checks on tools profile)
 - #144600 (Ensure external paths passed via flags end up in rustdoc depinfo)
 - #144609 (feat: Right align line numbers)
 - #144623 (miri subtree update)
 - #144626 (cc dependencies: clarify comment)
 - #144627 (Add a test case for the issue #129882)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit that referenced this pull request Jul 29, 2025
Rollup of 13 pull requests

Successful merges:

 - #144022 (Implementation: `#[feature(sync_nonpoison)]`, `#[feature(nonpoison_mutex)]`)
 - #144167 (Document why `Range*<&T> as RangeBounds<T>` impls are not `T: ?Sized`, and give an alternative.)
 - #144407 (fix(debuginfo): disable overflow check for recursive non-enum types)
 - #144451 (fix: Reject upvar scrutinees for `loop_match`)
 - #144482 (Add explicit download methods to download module in bootstrap)
 - #144500 (thread name in stack overflow message)
 - #144511 (tidy: increase performance of auto extra checks feature)
 - #144599 (bootstrap: enable tidy auto extra checks on tools profile)
 - #144600 (Ensure external paths passed via flags end up in rustdoc depinfo)
 - #144609 (feat: Right align line numbers)
 - #144623 (miri subtree update)
 - #144626 (cc dependencies: clarify comment)
 - #144627 (Add a test case for the issue #129882)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 9cba498 into rust-lang:master Jul 29, 2025
11 checks passed
@rustbot rustbot added this to the 1.90.0 milestone Jul 29, 2025
rust-timer added a commit that referenced this pull request Jul 29, 2025
Rollup merge of #144167 - zachs18:rangebounds-not-unsized-reason, r=tgross35

Document why `Range*<&T> as RangeBounds<T>` impls are not `T: ?Sized`, and give an alternative.

`Range*<&T> as RangeBounds<T>` impls have been tried to be relaxed to `T: ?Sized` at least twice:

* #61584
* #64327

I also was just about to make another PR to do it again until I `./x.py test library/alloc` and rediscovered the type inference regression, then searched around and found the previous PRs. Hence this PR instead so hopefully that doesn't keep happening 😛.

These impls cannot be relaxed for two reasons:

1. Type inference regressions: See ``@SimonSapin's`` explanation from a previous PR: #61584 (comment)
2. It's a breaking change: `impl RangeBounds<MyUnsizedType> for std::ops::Range<&MyUnsizedType>` is allowed after the coherence rebalance ([playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f704a6fe53bfc33e55b2fc246d895ec2)), and relaxing these impls would conflict with that downstream impl.

This PR adds doc-comments explaining that not having `T: ?Sized` is intentional[^1], and gives an explicit alternative: `(Bound<&T>, Bound<&T>)`.

Technically, the impls for the unstable new `std::range` types could be relaxed, as they are still unstable so the change would not be breaking, but having them be different in this regard seems worse (and the non-iterable `RangeTo/RangeToInclusive` range types are shared between the "new" and "old" so cannot be changed anyway), and then the type inference regression would pop up in whatever edition the new range types stabilize in.

The "see \<link\> for discussion of those issues" is intentionally left as a non-doc comment just for whoever may try to relax these impls again in the future, but if it is preferred to have the link in the docs I can add that.

Closes #107196 (as wontfix)
CC #64027

[^1]: "intentional" is maybe a bit of strong wording, should it instead say something like "was stabilized without it and it would be breaking to change it now"?
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request Jul 30, 2025
…ason, r=tgross35

Document why `Range*<&T> as RangeBounds<T>` impls are not `T: ?Sized`, and give an alternative.

`Range*<&T> as RangeBounds<T>` impls have been tried to be relaxed to `T: ?Sized` at least twice:

* rust-lang#61584
* rust-lang#64327

I also was just about to make another PR to do it again until I `./x.py test library/alloc` and rediscovered the type inference regression, then searched around and found the previous PRs. Hence this PR instead so hopefully that doesn't keep happening 😛.

These impls cannot be relaxed for two reasons:

1. Type inference regressions: See ``@SimonSapin's`` explanation from a previous PR: rust-lang#61584 (comment)
2. It's a breaking change: `impl RangeBounds<MyUnsizedType> for std::ops::Range<&MyUnsizedType>` is allowed after the coherence rebalance ([playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f704a6fe53bfc33e55b2fc246d895ec2)), and relaxing these impls would conflict with that downstream impl.

This PR adds doc-comments explaining that not having `T: ?Sized` is intentional[^1], and gives an explicit alternative: `(Bound<&T>, Bound<&T>)`.

Technically, the impls for the unstable new `std::range` types could be relaxed, as they are still unstable so the change would not be breaking, but having them be different in this regard seems worse (and the non-iterable `RangeTo/RangeToInclusive` range types are shared between the "new" and "old" so cannot be changed anyway), and then the type inference regression would pop up in whatever edition the new range types stabilize in.

The "see \<link\> for discussion of those issues" is intentionally left as a non-doc comment just for whoever may try to relax these impls again in the future, but if it is preferred to have the link in the docs I can add that.

Closes rust-lang#107196 (as wontfix)
CC rust-lang#64027

[^1]: "intentional" is maybe a bit of strong wording, should it instead say something like "was stabilized without it and it would be breaking to change it now"?
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Aug 1, 2025
Rollup of 13 pull requests

Successful merges:

 - rust-lang/rust#144022 (Implementation: `#[feature(sync_nonpoison)]`, `#[feature(nonpoison_mutex)]`)
 - rust-lang/rust#144167 (Document why `Range*<&T> as RangeBounds<T>` impls are not `T: ?Sized`, and give an alternative.)
 - rust-lang/rust#144407 (fix(debuginfo): disable overflow check for recursive non-enum types)
 - rust-lang/rust#144451 (fix: Reject upvar scrutinees for `loop_match`)
 - rust-lang/rust#144482 (Add explicit download methods to download module in bootstrap)
 - rust-lang/rust#144500 (thread name in stack overflow message)
 - rust-lang/rust#144511 (tidy: increase performance of auto extra checks feature)
 - rust-lang/rust#144599 (bootstrap: enable tidy auto extra checks on tools profile)
 - rust-lang/rust#144600 (Ensure external paths passed via flags end up in rustdoc depinfo)
 - rust-lang/rust#144609 (feat: Right align line numbers)
 - rust-lang/rust#144623 (miri subtree update)
 - rust-lang/rust#144626 (cc dependencies: clarify comment)
 - rust-lang/rust#144627 (Add a test case for the issue rust-lang/rust#129882)

r? `@ghost`
`@rustbot` modify labels: rollup
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-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RangeXxx<&T> should implement RangeBounds<T> even if T is unsized
4 participants