-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Allow const iterator implementations #102225
Conversation
r? @thomcc (rust-highfive has picked a reviewer for you, use r? to override) |
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
cc @rust-lang/wg-const-eval |
☔ The latest upstream changes (presumably #102234) made this pull request unmergeable. Please resolve the merge conflicts. |
This comment has been minimized.
This comment has been minimized.
98284d6
to
3e1fbda
Compare
☔ The latest upstream changes (presumably #102265) made this pull request unmergeable. Please resolve the merge conflicts. |
Once this lands I can take on const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The drop in place change could go into a separate PR, seems good on its own
On the rest of the PR: quite a few annoyingly big bootstrap diffs, not sure how I feel about them. But I also don't want to block this for a month
library/core/src/array/mod.rs
Outdated
// SAFETY: slice contains initialized objects | ||
unsafe { crate::ptr::drop_in_place(x) } | ||
} | ||
crate::intrinsics::const_eval_select((to_drop,), drop_ct, drop_rt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be needed more often, maybe move into drop_in_place
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can extract this into a separate function, but not to drop_in_place as drop_in_place
is for all unsized types and this is only for slices.
Hmm, this is really dependent on the change from 2 days ago, I take it? My instinct was also that it would be nice to wait for the bootstrap bump, but if it's 6 weeks that's not amazing. Certainly a bunch of this -- like constifying the adaptor constructors -- is an easy "sure", though. |
Im not sure its actually possible to do const Iterator for slices, since those rely on many pointer operations that are not sound in const context. pub struct Iter<'a, T: 'a> {
ptr: NonNull<T>,
end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
// ptr == end is a quick test for the Iterator being empty, that works
// for both ZST and non-ZST.
_marker: PhantomData<&'a T>,
} library/core/src/slice/iter/macros.rs: has the |
We recently moved to attributes on the entire trait instead of marking individual functions as const. As a result of this, we can't simply constify adaptors separately.. |
efd3979
to
8240186
Compare
Could this maybe be reduced in scope by only making |
No as @fee1-dead said above there was a recent change that disabled partially const Traits. (only allow const implementations for traits with the #[const_trait] attribute) Partially const Traits were removed, since a ~const Trait bound would not actually mean that the concrete type used actually has the const functions needed. |
This seems unfortunate, since it also means that we're effectively saying that t-libs-api is only allowed to make const iterator methods (or else Rust users can't use iterators in const). That might be reasonable, but it's a big restriction that seems worth considering. |
Keyword generics might allow syntax like this to allow non const functions in traits: const<C> Trait {
const<C> fn const_fn() { ...}
fn non_const_fn() {...}
} But otherwise I don't know how to make some trait functions never const. (Other than adding some kind of #[never_const] attribute which would be very weird in my opinion) |
That should make this a libs-api concern |
Re-requesting review, since this now uses |
Even if we don't have stable partially const traits enabling that unstably would still bring the benefit of reducing the amount of API surface we need to constify, which is one of the issues with this type of "experimenting with const syntax" PR.
If
It's be quite the hack to explicitly declare the whole thing is const and then go "oops, you can't actually call this in const contexts". That's exactly the time where you'd need a partially const trait to make this explicit. |
const fn collect< | ||
'a, | ||
T: ~const Iterator, | ||
R, | ||
O: ~const FromIterator<<<T as Iterator>::Item as Try>::Output>, | ||
>( | ||
x: GenericShunt<'a, T, R>, | ||
) -> O | ||
where | ||
T::Item: ~const Try<Residual = R>, | ||
R: ~const Destruct, | ||
{ | ||
x.collect() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks terrible, can the generic constraints be moved to where bounds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
move |(), (t, u)| { | ||
a.extend_one(t); | ||
b.extend_one(u); | ||
pub struct ExtendFold<'a, EA, EB>(&'a mut EA, &'a mut EB); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a temporary thing to be removed later? If so it could use a FIXME(#issuenumber) for the feature needed to solve it.
If this isn't meant to be temporary I have additional concerns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is temporary. This could be improved and made to look better using ConstFnMutClosure
, but in the long run we plan to replace these with const closures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've improved it.
There's some ongoing work for namable function items. Would it be possible to have conditionally-const |
The serious design concerns make the described language feature perma-unstable if they cannot be resolved.
We are not panicking at runtime, though? This would only result in compile errors when called. I would consider adding a perma-unstable language feature for this to be a hack as well.
I guess. It will certainly need more compiler work in addition to namable function item types to make this happen. I was hoping that we could make comparisons between two slices possible in compile time. Its current default implementation uses iterator combinators. (see) The thing is that all of these are doable and look way better than the one I did a year ago (#92433) It is a real concern in terms of readability since not many people understand what |
This comment was marked as resolved.
This comment was marked as resolved.
fc49fe2
to
27bd174
Compare
This comment has been minimized.
This comment has been minimized.
27bd174
to
8249c6c
Compare
The job Click to see the possible cause of the failure (guessed by this bot)
|
☔ The latest upstream changes (presumably #105512) made this pull request unmergeable. Please resolve the merge conflicts. |
This comment was marked as off-topic.
This comment was marked as off-topic.
I'll tentatively remove T-compiler from the review queue as the code in this patch seems now to be all under @rustbot label -T-compiler |
…o, r=thomcc implement const iterator using `rustc_do_not_const_check` Previous experiment: rust-lang#102225. Explanation: rather than making all default methods work under `const` all at once, this uses `rustc_do_not_const_check` as a workaround to "trick" the compiler to not run any checks on those other default methods. Any const implementations are only required to implement the `next` method. Any actual calls to the trait methods other than `next` will either error in compile time (at CTFE runs), or run the methods correctly if they do not have any non-const operations. This is extremely easy to maintain, remove, or improve.
…o, r=thomcc implement const iterator using `rustc_do_not_const_check` Previous experiment: rust-lang#102225. Explanation: rather than making all default methods work under `const` all at once, this uses `rustc_do_not_const_check` as a workaround to "trick" the compiler to not run any checks on those other default methods. Any const implementations are only required to implement the `next` method. Any actual calls to the trait methods other than `next` will either error in compile time (at CTFE runs), or run the methods correctly if they do not have any non-const operations. This is extremely easy to maintain, remove, or improve.
…r=the8472,fee1-dead Allow using `Range` as an `Iterator` in const contexts. ~~based on rust-lang#102225 by `@fee1-dead~~`
Based on #102224