Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upAmend #911 const-fn to allow unsafe const functions #1245
Conversation
This comment has been minimized.
This comment has been minimized.
|
I have implemented this in a branch (won't PR until this RFC is accepted). Link Appears to work properly with just a simple change to the parser. |
This comment has been minimized.
This comment has been minimized.
|
Yay! For motivation: The |
This comment has been minimized.
This comment has been minimized.
|
Other motivation is NonZero and Unique, which underlie most collections. Having these be able to be const allows empty collections to be compile-time constructed. |
This comment has been minimized.
This comment has been minimized.
|
@Ericson2314 |
This comment has been minimized.
This comment has been minimized.
|
I think it should be made clear somewhere that |
This comment has been minimized.
This comment has been minimized.
|
@glaebhoerl constants are pure right now, so unsafety at compile-time is out of the question. |
eddyb
reviewed
Aug 12, 2015
| ```rust | ||
| struct OptionalInt(u32); | ||
| impl OptionalInt { | ||
| /// Value must be non-zero |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
thepowersgang
Aug 12, 2015
Author
Contributor
Possibly, however Unique is more directly related to the collection types (as that's the libcore type they're built on)
This comment has been minimized.
This comment has been minimized.
|
@eddyb Oops, I've discussed this on IRC, probably with you. For the short term, |
nrc
added
the
T-lang
label
Aug 13, 2015
This comment has been minimized.
This comment has been minimized.
|
@Ericson2314 That's still problematic, what would it do for |
This comment has been minimized.
This comment has been minimized.
|
Sandbox compile time evaluation. For this case, I think it would suffice to keep an extra "taint flag" on pointer values, and not allow dereferencing tainted ones. |
aturon
self-assigned this
Aug 13, 2015
This comment has been minimized.
This comment has been minimized.
|
@glaebhoerl I would assume that's implicit in the idea of CTFE... but it may require explicit stating in the RFC. |
This comment has been minimized.
This comment has been minimized.
jmesmon
commented
Sep 8, 2015
|
I'd like to note that in the common usage of rust via cargo with build scripts, or nightly rust using plugins, we already have potentially undefined things occurring at compile time. If there is a goal to avoid particular types of undefined things at compile time, but not all of them, within the rust project there probably should be some explicit note (somewhere, not necessarily this RFC) about what the goals are around undefined things occurring at compile time. Edit: I suppose it might just be "avoid vulnerabilities in play.rust-lang.org" |
This comment has been minimized.
This comment has been minimized.
|
@thepowersgang Sorry for the long silence here! I'm working my way through RFC backlog. I personally don't see any problem with this RFC. I will propose it for "final comment period" in the next Lang Team meeting. |
aturon
added
the
final-comment-period
label
Sep 21, 2015
This comment has been minimized.
This comment has been minimized.
|
This RFC is entering its final comment period. |
This comment has been minimized.
This comment has been minimized.
|
|
petrochenkov
reviewed
Sep 24, 2015
| struct OptionalInt(u32); | ||
| impl OptionalInt { | ||
| /// Value must be non-zero | ||
| unsafe const fn new(val: u32) -> OptionalInt { |
This comment has been minimized.
This comment has been minimized.
petrochenkov
Sep 24, 2015
Contributor
Since const is not a part of function type and unsafe is, I'd prefer this to be const unsafe fn and not unsafe const fn
This comment has been minimized.
This comment has been minimized.
nagisa
Sep 24, 2015
Contributor
“unsafe constant function” sounds more “right” to me than “constant unsafe function”, though your point is also valid.
Either way, I think it should be possible to put these in any order. I’ve already had some trouble remembering which goes first in pub extern fn x and now I’ll have to think what order pub, const and unsafe go in pub unsafe const fn x. pub is pretty easy since it “always goes first”, but there’s no such obvious rule for unsafe and const.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
eddyb
Sep 25, 2015
Member
I prefer unsafe const fn because I see const fn as something different from fn, while unsafe is a mere qualifier.
There's no real reason why there aren't const fn() pointer types, they just weren't implemented.
This comment has been minimized.
This comment has been minimized.
dgrunwald
Sep 30, 2015
Contributor
+1 for @nagisa: allow both orders
There's no good reason to force users to learn a particular order.
If we decide on a preferred order, that can still be enforced by rustfmt. No need to make rustc overly strict.
This comment has been minimized.
This comment has been minimized.
thepowersgang
Sep 30, 2015
Author
Contributor
Hmm... both could be allowed, but would complicate the parser (if it is to correctly disallow unsafe const unsafe fn). I'll yeild to the language team on the final decision, but I'm leaning towards keeping a fixed order.
This comment has been minimized.
This comment has been minimized.
huonw
Oct 3, 2015
Member
I agree with @petrochenkov: unsafe fn feels like a more fundamental concept/thing than const fn. (const on a function doesn't outlaw it from being used as a non-const function, while unsafe does outlaw it from being used as a non-unsafe one.)
This comment has been minimized.
This comment has been minimized.
Ericson2314
Oct 3, 2015
Contributor
@eddyb I see how a const fn ptr could allow for higher order functions at compile-time, I am not sure that is the right means to achieve that.
This comment has been minimized.
This comment has been minimized.
|
It's official. The language design subteam has decided to accept this RFC. We did not, however, resolve the burning question of modifier order. We'll have to figure that out next week. |
aturon
added a commit
that referenced
this pull request
Oct 9, 2015
aturon
merged commit f430e8b
into
rust-lang:master
Oct 9, 2015
This comment has been minimized.
This comment has been minimized.
|
This RFC has been merged. The lang team met and discussed this RFC again, and decided that:
And, as @nikomatsakis said already, in general we are in favor of the RFC. |
aturon
removed
the
final-comment-period
label
Oct 9, 2015
This comment has been minimized.
This comment has been minimized.
|
@jmesmon (late response, I've only just gathered some thoughts)
That's the down-to-earth view of it, yeah. But as an example of why this would bother me more deeply, consider that The examples of cargo scripts and especially compiler plugins are similar in a way, but feel qualitatively different to me (perhaps it's the distinction between arbitrary and undefined). |
thepowersgang
referenced this pull request
Oct 10, 2015
Merged
Implement RFC #1245 : `unsafe const fn` #28827
thepowersgang
referenced this pull request
Oct 17, 2015
Closed
unsafe const fn declaration order #29107
nagisa
referenced this pull request
Oct 24, 2015
Merged
Edit #911 - The order `const unsafe fn` was chosen (rust-lang/rust#29107) #1335
This comment has been minimized.
This comment has been minimized.
Parakleta
commented
Oct 26, 2015
|
It would be ideal if this change could be applied to |
This comment has been minimized.
This comment has been minimized.
|
@Parakleta That's pretty difficult, as it requires representing values as polysemantic bags of bits (for example, constant references right now are only the value they point to, they have no address associated with them until runtime). Our const evaluation is seriously lacking even without this massive increase in complexity you are proposing. |
This comment has been minimized.
This comment has been minimized.
Parakleta
commented
Oct 27, 2015
|
I don't understand why dereferencing a pointer created from an integer through |
This comment has been minimized.
This comment has been minimized.
|
@Parakleta How would you implement it? Memory doesn't exist at compile-time. |
This comment has been minimized.
This comment has been minimized.
Parakleta
commented
Oct 27, 2015
|
Managed memory doesn't, since you expect the runtime to make it for you when the program is launched, but unmanaged memory does. Specifically look at the memory mapped registers of any MCU. I want something like |
This comment has been minimized.
This comment has been minimized.
Parakleta
commented
Oct 27, 2015
|
I just realised we're talking about slightly different things. In your example taking the address of a constant integer wouldn't work, it would need to force the integer to be static, and then taking the address is fine. So |
This comment has been minimized.
This comment has been minimized.
|
You already have And no, the concept of memory does not exist at compile-time. Managed or unmanaged. At compile-time you can only deal with safe symbolic references, mutable variables at most (as long as you preserve "execution order"). Once you introduce transmutes, you have to track every bit and where it comes from, and somehow allow reconstructing symbolic values from the shattered bits of a different symbolic value (in this context, a safe reference). Constructing symbolic references from constant integers would be impossible, as there is no symbolic information associated to any constant integer address. |
This comment has been minimized.
This comment has been minimized.
Parakleta
commented
Oct 27, 2015
|
You're right, I'm not really following your argument too well, the point I'm stuck at is just that I cannot get a pointer to the data within a |
This comment has been minimized.
This comment has been minimized.
|
The bits of a reference do not exist at compile-time, as the address is decided at link or load time. Can you dereference arbitrary pointers or perform arithmetic on addresses of statics in C constant expressions (or C++11 constexpr)? |
This comment has been minimized.
This comment has been minimized.
|
When using the Python C API, it's normal to cast function pointers within static initializers: static PyMethodDef cc_methods[] = {
{"varargs", function_with_varargs, METH_VARARGS, NULL},
{"keywords", (PyCFunction)function_with_kwargs, METH_KEYWORDS, NULL},
{0}
};
Currently there doesn't seem to be any way to do the same operation in Rust; for rust-cpython I've had to use |
This comment has been minimized.
This comment has been minimized.
Parakleta
commented
Oct 27, 2015
|
The bits of a reference do not, but the type does and at compile time I can change the type that those bits are intended to represent even if the bits are still unknown. Arithmetic on the addresses of statics is done to some extent at link time to address into arrays and structs, although I don't know how general purpose this is, maybe just offsets. I think I understand now that your concern is that transmute would make |
This comment has been minimized.
This comment has been minimized.
|
@dgrunwald That's one of those cases that makes me sad we didn't go with some combination of reference/pointer to Technically, we could support the cast with the current |
thepowersgang commentedAug 9, 2015
See discussion in #1207