Calling methods on generic parameters of const fns by oli-obk · Pull Request #2632 · rust-lang/rfcs (original) (raw)
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 andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Conversation230 Commits37 Checks0 Files changed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})
TLDR: Allow
const fn add<T: Add>(a: T, b: T) -> T::Output { a + b }
and
pub struct Foo<T: Trait>(T);
impl<T: ?const Trait> Foo {
fn new(t: T) -> Self {
// not calling methods on t
, so we opt out of requiring
// <T as Trait>
to have const methods via ?const
Self(t)
}
}
cc @Centril @varkor @RalfJung @eddyb
This RFC has gone through an extensive pre-RFC phase in rust-lang/const-eval#8
Triage: pFCP comment: #2632 (comment)
varkor, cramertj, ebkalderon, clarfonthey, gnzlbg, solson, Centril, japaric, Thomasdezeeuw, taiki-e, and 79 more reacted with thumbs up emoji RalfJung, cramertj, mark-i-m, clarfonthey, 00imvj00, gnzlbg, solson, Centril, japaric, taiki-e, and 23 more reacted with hooray emoji clarfonthey, gnzlbg, solson, Centril, japaric, burdges, wesleywiser, jieyouxu, darksv, ohsayan, and 12 more reacted with heart emoji kennytm, mental32, peter-lyons-kehl, lvyitian, and Creative-Difficulty reacted with eyes emoji
One alternative syntax design that is not mentioned here is the question of const impl versus impl const.
There are strong arguments that const impl
is the more consistent syntax, as it is consistent both with the existing practice of prefixing modifiers to impl
(default impl
, unsafe impl
, etc.) and prefixing const
to keywords to indicate const variants (e.g. const fn
[and the hypothetical const trait
]).
Conversely, as far as I'm aware, impl const
is not consistent with any existing syntax in the language or this RFC.
(I don't like to start the discussion with syntax bikeshedding, but as mentioned in the original post, this RFC has already ungone significant design discussion and I'm satisfied it's close to the optimal conservative design.)
l4l, rpjohnst, mark-i-m, ssokolow, matthieu-m, DDOtten, huhlig, gnzlbg, maksimsco, taiki-e, and 19 more reacted with thumbs up emoji DDOtten, huhlig, gnzlbg, kestred, izik1, oilaba, and lvyitian reacted with heart emoji
Relevant to the language team, which will review and decide on the RFC.
Syntax related proposals & ideas
Type system related proposals & ideas
Proposals relating to compile time evaluation (CTFE).
labels
How do we want -> impl Trait
and arg: dyn Trait
to interact with const fn
? If you must specify -> impl const Trait
, does it also make sense to require arg: dyn const Trait
? Both cases feel more existential-y and thus less tied to the function's type parameters, so I kind of lean that way for consistency.
I imagine it makes most sense to use the same (syntactic) rules for impl Trait
and dyn Trait
as for parameter bounds: that is, in const fn
, an impl Trait
actually means impl const Trait
/const impl Trait
(and similarly for dyn
) and impl ?const Trait
/?const impl Trait
allows opting-out of constness.
This comment has been minimized.
Co-Authored-By: oli-obk github35764891676564198441@oli-obk.de
I'm not sure why const Drop
must be recursive on fields. In my mental model, the body of drop
doesn't have calls to the fields' drop impls inserted, but rather, it's the role of drop glue to piece them all together:
{ let local = get_thing();
// Implicitly inserted
// (each one is individually omitted if that type
// does not explicitly implement Drop)
Drop::drop(&mut local);
Drop::drop(&mut local.field_1);
Drop::drop(&mut local.field_2);
}
Requiring const Drop
on fields increases churn when library A cannot write const Drop
yet due to a non-const Drop in library B. (so to use A in a const context, changes now need to be made to both library B and A in that order, instead of just B).
(one could argue that allowing impl const Drop
in library A when a field is non-const Drop
could lead to misleading documentation; but another thread of discussion on this PR seems to be arriving at the conclusion that we additionally require an auto-trait like ConstDrop, which partially mitigates this concern)
I don’t think this has been mentioned before, but putting
const
beforeimpl
would be more consistent with other modifiers likeunsafe
andpub
if we decided to do that.
It has been mentioned before. This was even the original syntax. Reasoning for the change can be found at rust-lang/const-eval#8 (comment)
cc @scottmcm for consistency (not in semantics, but user expectations) I have slowly come back around to const impl Trait for Type
being the best syntax.
Ultimately the location of const
is really nothing but the color of the bikeshed. impl const
may be different from the other things, but it is not that hard to remember this "exception" when you have things like T: ?const Trait
.
Conceptually, the keyword is attached to the trait. I.e. it's not an impl const
of a Trait
, but rather an impl
of a const Trait
.
fstirlitz, oli-obk, Lokathor, scottmcm, Coder-256, CAD97, demurgos, RagibHasin, Zenithsiz, o-x-e-y, and 2 more reacted with thumbs up emoji
Conversely, as far as I'm aware,
impl const
is not consistent with any existing syntax in the language or this RFC.
I think that's looking at it from the wrong perspective.
It's not that it's (impl const) Trait
, but that it's impl (const Trait)
, the same as you can impl (dyn Trait)
. And that's consistent with something like struct Foo<T: const Default>(T);
or similar.
But as far as I can tell, the Constness is not a property of the Trait, but of the impl, which is not the same for dyn, right?
It's not that it's
(impl const) Trait
, but that it'simpl (const Trait)
, the same as you canimpl (dyn Trait)
. And that's consistent with something likestruct Foo<T: const Default>(T);
or similar.
I agree with this in particular when viewed in light of effect systems. Moreover, impl const Trait
also has composability benefits, e.g. arg: impl Add + ?const Clone + const Debug
vs. arg: const impl Add + Cone + Debug
are probably not the same semantically.
But as far as I can tell, the Constness is not a property of the Trait, but of the impl, which is not the same for dyn, right?
Traits can be seen as logical requirements and implementations are proofs that those requirements are satisfied. In that light, e.g. T: const Foo
can be seen as a constraint that T
satisfies const Foo
and impl const Foo for MyT
is a witness for that.
Co-Authored-By: oli-obk github35764891676564198441@oli-obk.de
luser mentioned this pull request
A problem came up with the original plan, described in rust-lang/rust#83452 and on Zulip: under some conditions, we currently accept const fn
on stable that have trait bounds in scope; if we say that all trait bounds on const fn
are implicitly const Trait
(as proposed in this RFC), that would be a breaking change for callers of these functions.
Should we try to revert that support, @RalfJung? I think it was accidental.
@nikomatsakis That might be good if we want to keep our options open -- but @oli-obk has the overview here, I'm just reporting what came up elsewhere. I don't currently have the bandwidth to work on this.
I personally am leaning towards a different design than the one proposed in the RFC, one where there is no implicit "callable in const context" -- that would be more consistent with &dyn Trait
and fn()
which can already be created in const
. That design doesn't mind this accident. But this is a discussion for the RFC.
What's the status of the RFC? FCP was proposed over two years ago, and is currently blocked by @withoutboats. I will note that boats is an alumnus of the lang team. While I am not dismissing their concerns outright, they have had zero public activity on GitHub in over six months. At this point, is it worth cancelling and restarting the checkboxes? This would permit the current lang team to register the same concerns if they still exist.
cc lang team: @joshtriplett @nikomatsakis @cramertj @pnkfelix @scottmcm
I'd assume experimentation going on based upon #2632 (comment) ? If I read correctly, there was a rather extensive discussion around boats' third issue, which prompted a desire to experiment.
Yeah, the main reason I asked is because said experimentation had taken place and been on nightly for a while now.
There are currently still a few things that make the experimental feature useless in practice. We don't have the implementation capacity right now to work on it, but I do plan on more things happening here this year.
I talked to @oli-obk today and we agreed that we will close this RFC for now. The content is likely still desired but we want to do more experimentation and will re-open when the design seems closer to settled.
IIUC, this RFC would make trait-associated constants unusable in const contexts if the trait bound is not declared const
(possibly implicitly). I think this would be a design mistake - an unnecessary reduction of usability. Conceptually, associated constants should be usable in const contexts always, irrespective of the constness of the trait implementation or the trait bound (setting aside for now the implementation difficulties of proving the equality of different constant expressions). Here's an example that wouldn't compile given the current design:
trait Foo { fn foo(value: u8) -> u8; }
trait Bar { const BAR: u8;
fn bar(value: u8) -> u8;
}
const fn baz() -> u8
where T: Foo + ?const Bar {
T::foo(T::BAR) // error: <T as Bar>
used in a const context
}
Reviewers
fbstj fbstj left review comments
comex comex left review comments
pnkfelix pnkfelix left review comments
RalfJung RalfJung left review comments
kpp kpp left review comments
Centril Centril left review comments
gnzlbg gnzlbg left review comments
ExpHP ExpHP left review comments
cramertj cramertj left review comments
CAD97 CAD97 left review comments
jD91mZM2 jD91mZM2 left review comments
RustyYato RustyYato left review comments
eira-fransham eira-fransham left review comments
Labels
Proposals relating to compile time evaluation (CTFE).
Effects related proposals & ideas
Syntax related proposals & ideas
Type system related proposals & ideas
Relevant to the language team, which will review and decide on the RFC.