-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Make size
an associated constant
#1168
Conversation
I definitely want this, but the implementation is non-trivial, since you need to call into llvm to obtain this value. That is usually only done in trans, but for this to be a constant it needs to be available much earlier. |
This is super wacky and I think I love it. It would also let us ditch the |
I love this; it's so obvious in hindsight... but I have one concern: having these on every type seems a little out of proportion to how often this information would presumably be needed. I'm still marginally in favour of const functions for that reason. |
Functions don't have to be freestanding - maybe the |
But then maybe associated constants would make more constant expressions possible... |
@diwic My concern is that putting anything on the |
You can always define a |
@DanielKeep I see your point, but for perspective, |
I find myself rather in love with this idea. It's elegant, simple, and just makes sense. |
Note #1062, which would have to be accepted first (and in fact, that RFC mentions this very idea in one of the examples). I am generally in favor of this, modulo backwards compatibility issues. I have always though that size/alignment in bytes made more sense as associated consts than const functions. |
Correction, #1062 does not actually have to be accepted for this, but if it isn't, you won't be able to use Further edit: This is orthogonal to the issue of having a const function versus an associated const, since in both cases the issue is actually the ability for the value of a constant expression to depend on a type parameter at all, regardless of the mechanism. |
I wouldn't worry about a BC hazard here. I'd expect exactly 0% of stable Rust code to have a problem since associated constants are still unstable, and so there's no reason for anyone to be using ALL_CAPS_CASE for an associated item (let alone the specific identifiers |
Allowing associated consts as |
@arielb1 I guess that this was what I was trying to clarify in my second comment. I don't think that the syntax really matters for the #1062 issue. If you have But if you allow the size of a type parameter to be used in a constant expression (e.g. an array size), you will definitely hit the #1062 issue, regardless of whether you accomplish this by using an associated const or by making |
This seems very nice, if we figure out the details around implementation. |
This would be adding |
Minor point: there are non- |
@alexcrichton Couldn't someone just grab all the crates.io packages and grep for every instance of |
I would prefer making
Not entirely accurate. We already do a lot of size/alignment computations ourselves for aggregates; the algorithm for structs is straight-forward and enums get their LLVM type after variants have been laid out. A big chunk of |
@huonw, are there any types which have a size but no alignment? Off the top of my head I don't think so, and I wonder if an Aligned OIBIT that Sized derives from would be possible, i.e. trait Aligned { const ALIGNMENT: usize; }
trait Sized: Aligned { const SIZE: usize; } I don't think that would break any existing code, though I could be wrong. EDIT: In the long run, that might be useful for informing the compiler of alignment constraints on a type, but I'm not suggesting that be supported at the moment. |
@eternaleye it wouldn't need to be OIBIT, it could be implemented by the compiler for all sized types (and also I should also mention that lifting layout computation up from trans would allow us to operate with less known information, e.g. |
We discussed in the language design subteam meeting and decided that while we like this idea, it is premature, given the current state of associated constants. Therefore, we are going to close the RFC for the time being, and revisit this approach once associated constants are in better shape. Thanks very much for the writeup! |
Greetings from the future! Associated consts are on the verge of being stabilized ( rust-lang/rust#29646 ), likely landing in 1.20, so as per @nikomatsakis' comment I think it may be time to un-postpone this RFC. @eddyb re: "I would prefer making size_of and align_of the stable interface, even if associated constants are being used under the hood", do you still hold this opinion? IMO, |
@bstrie As @alexcrichton mentioned above, I'm not sure we could do that backwards compatibly-- there are almost certainly types with methods called |
@cramertj I'll dispute the "almost certainly" claim, I think it's vanishingly unlikely that we'll find any types that defy convention (in defiance of the default-on style lint) to give themselves an all-uppercase method name like that. Of course, I still welcome a crater run to determine this (or are we on cargobomb by now?). That said, if we do want to ever do this, it's true that we should take action to reserve the names before associated consts reach the stable channel. |
@bstrie yeah, we can certainly check. I was surprised that someone had a struct named If crater is clean, we can probably just do a warning cycle. Still, I personally prefer the |
You can always write |
You can implement the associated constant version, in a library, using the intrinsic. |
One issue with making it a constant is that changing the size of an object becomes a breaking change, because people might code things in constants like |
You can do that with |
@cramertj |
@eddyb re: "I prefer size_of because it's used everywhere already and some of that code can become CTFE-enabled.", but |
Regarding @oli-obk 's good point about changing size becoming a breaking change, perhaps the size should not be exported for structs that have private fields? I guess changing a size is sort-of already a breaking change, since other crates can see the size at run time. It just can't currently cause compilation to fail... |
Or just document it? At some point, every change is a breaking change... |
Yeah, the more I think about it, the more I think that you really don't want to prevent code from creating types based on the size of anything, and code that breaks when the size changes is broken code. After all, the point of using the const sizes is to properly handle the case when there size changes! |
I'm strongly against polluting the namespace of every single type with something that is mostly useful in a subset of contexts (FFI most likely). I personally never had to use With the change applied, in IDE's, So while I'm not against the general idea of having an associated constant (I understand why it can be seen as advantageous over a const fn), can this be be opt in at usage site? As in, you have to |
Yes, that it what is probably going to happen: rust-lang/rust#43017. Not sure about the timeframe, there is still some discussion going on about whether all |
(rendered)
Personally I'd prefer lower case names such as
size
andalignment
for these associated constants, but I guess upper case is more in line with other Rust guidelines.