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 upCalling methods on generic parameters of const fns #2632
Conversation
oli-obk
added some commits
Oct 5, 2018
This comment has been minimized.
This comment has been minimized.
|
One alternative syntax design that is not mentioned here is the question of There are strong arguments that Conversely, as far as I'm aware, (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.) |
cramertj
reviewed
Feb 5, 2019
fbstj
reviewed
Feb 5, 2019
Centril
added
T-lang
A-syntax
A-typesystem
A-const-eval
labels
Feb 5, 2019
This comment has been minimized.
This comment has been minimized.
rpjohnst
commented
Feb 5, 2019
|
How do we want |
This comment has been minimized.
This comment has been minimized.
|
I imagine it makes most sense to use the same (syntactic) rules for |
This comment has been minimized.
This comment has been minimized.
|
I don’t think this has been mentioned before, but putting |
This comment has been minimized.
This comment has been minimized.
ExpHP
commented
Feb 6, 2019
•
|
I'm not sure why {
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 (one could argue that allowing |
This comment has been minimized.
This comment has been minimized.
It has been mentioned before. This was even the original syntax. Reasoning for the change can be found at rust-rfcs/const-eval#8 (comment) cc @scottmcm for consistency (not in semantics, but user expectations) I have slowly come back around to |
This comment has been minimized.
This comment has been minimized.
ExpHP
commented
Feb 10, 2019
|
Ultimately the location of Conceptually, the keyword is attached to the trait. I.e. it's not an |
Centril
self-assigned this
Feb 14, 2019
This comment has been minimized.
This comment has been minimized.
I think that's looking at it from the wrong perspective. It's not that it's |
This comment has been minimized.
This comment has been minimized.
|
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? |
This comment has been minimized.
This comment has been minimized.
I agree with this in particular when viewed in light of effect systems. Moreover,
Traits can be seen as logical requirements and implementations are proofs that those requirements are satisfied. In that light, e.g. |
oli-obk
added some commits
Feb 16, 2019
Centril
added
the
A-effects
label
Feb 16, 2019
Centril
reviewed
Feb 16, 2019
This comment was marked as off-topic.
This comment was marked as off-topic.
Coder-256
commented
Mar 12, 2019
I was under the impression that const functions would always be implicitly evaluated at compile-time when given const parameters. Does that only apply to variables declared with |
This comment was marked as off-topic.
This comment was marked as off-topic.
rpjohnst
commented
Mar 12, 2019
That is incorrect. They will only be evaluated at compile time when called from a const context. For example, |
This comment was marked as off-topic.
This comment was marked as off-topic.
Coder-256
commented
Mar 12, 2019
|
@rpjohnst Ok that makes a lot of sense, thank you for clarifying. One final question: if you were to disable all compiler optimizations (ex. |
This comment was marked as off-topic.
This comment was marked as off-topic.
|
@Coder-256 I'm hesitant to make such guarantees for all time; but e.g. if a function may panic and we move that to compile time it would be a compile time error which seems like an unlikely change. But we could prove that it will terminate and then execute it at compile-time... Why is the guarantee not to important? |
This comment was marked as off-topic.
This comment was marked as off-topic.
Coder-256
commented
Mar 12, 2019
|
@Centril It's 100% an edge case, so it's not super important for most code, but for example, benchmarking code would be a good place to have that guarantee. Although that may be out of the scope for this RFC since it would not break anything. Also, sorry for the barrage of questions, but wouldn't this use of the const fn foo() {
const result = bar();
result
}Here's what the current Rust book says:
However, if |
This comment was marked as off-topic.
This comment was marked as off-topic.
rpjohnst
commented
Mar 12, 2019
|
In practice, at least for the near to mid-future, any non- If you need to guarantee that something happens at runtime (like for benchmarking), you thus cannot rely on anything to do with
This is why the RFC went with the syntax const fn foo<T: const /* <- this is extra, beyond the RFC */ Trait>() {
const result = T::bar(); // this is now allowed, even when `foo` is called from a non-const context
result
} |
This comment was marked as off-topic.
This comment was marked as off-topic.
Lokathor
commented
Mar 12, 2019
|
@rpjohnst at what point, if ever, could const things be compile time evaluated even when bound with |
This comment was marked as off-topic.
This comment was marked as off-topic.
Ekleog
commented
Mar 12, 2019
|
@Lokathor All the time: https://play.rust-lang.org/?version=stable&mode=release&edition=2018&gist=e91e27e7996a664fb38290bcc0c78207 (select “ASM” near the “Build” button) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Lokathor
commented
Mar 13, 2019
|
Except that they specifically said in a comment above that such a thing isn't guaranteed. So it might work for any particular simple example, but that's not at all assured. |
This comment was marked as off-topic.
This comment was marked as off-topic.
rpjohnst
commented
Mar 13, 2019
|
What exactly are you asking? We interpreted you question as "when is compile-time evaluation allowed in a If so, I suspect the answer is "never." We have |
This comment was marked as off-topic.
This comment was marked as off-topic.
Lokathor
commented
Mar 13, 2019
|
Yeah I was asking about the second thing. If let a = some_const_fn(some_const_val);Is ever different from const c: whatever = some_const_fn(some_const_val);
let a = c;Then that just seems like a big performance/ergonomics footgun. The shorter, easier to type version should, all else being equal, always be just as performant as the long winded version. We don't need that guarantee immediately, but we should strive to attain that guarantee eventually. |
This comment was marked as off-topic.
This comment was marked as off-topic.
rpjohnst
commented
Mar 13, 2019
No, we should not, for the same reasons that we don't infer It's also not straightfoward whether compile-time evaluation is always better for performance! The default choice of letting the optimizer decide is probably a safer bet- its heuristics can be improved without modifying program source. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Coder-256
commented
Mar 13, 2019
•
|
@Ekleog I'm no expert, but I'm pretty sure that's because of optimization. Change Release to Debug and you'll see what I mean. Optimization and @rpjohnst Just to confirm, in my example, const fn add_const_test<T: Add>(a: T, b: T) -> T {
const result = a + b;
result
}
fn foo() -> u8 {
add_const_test(generate_random_u8() / 2, 5)
}Even though we write
I don't think that it's a breaking change (since it is additive), but it does redefine existing usage of the |
This comment was marked as off-topic.
This comment was marked as off-topic.
rpjohnst
commented
Mar 13, 2019
|
Yes, though that change has already happened- you can already write |
This comment was marked as off-topic.
This comment was marked as off-topic.
Coder-256
commented
Mar 13, 2019
|
@rpjohnst Ok thank you for clarifying that. In that case I'm pretty sure that the book needs to be updated... should I open an issue there? |
This comment was marked as off-topic.
This comment was marked as off-topic.
Ekleog
commented
Mar 13, 2019
•
|
@Coder-256 They definitely are different, indeed. The question I gave an answer to was “When is the compiler allowed to compile-time-evaluate in non-const contexts?”, to which the answer is “All the time” (due to optimization). It sounds like the question was actually “When is the compiler forced to optimize in non-const contexts”, to which the answer @rpjohnst gave is “Never”. :) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Lokathor
commented
Mar 13, 2019
|
@rpjohnst can you give an example of a compile time evaluation of an expression hurting runtime performance compared to that expression being computed at runtime? I mean obviously it will hurt compile time, but when could it hurt runtime performance to enforce that an expression is evaluated at compile time? |
This comment was marked as off-topic.
This comment was marked as off-topic.
rpjohnst
commented
Mar 13, 2019
|
I'm thinking along the same lines as generic function monomorphization- there's a space/time tradeoff here, and sometimes choosing to use more space unfortunately comes back around and slows down the program. Doing too much compile-time evaluation could have the same effect- binary bloat by storing lots of constants in memory that could just be computed on the fly when used. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Note that that question is entirely off-topic for this RFC. You are discussing compiler optimizations here. The compiler will transform your program in arbitrary ways if it thinks that helps with performance, and it will promise not to change the programs observable behavior in the process. Rust makes no promise of optimizations happening or not happening. This RFC is not at all about optimizations. CTFE and const propagation are almost entirely unrelated, at least conceptually. Please let's stick to CTFE here, and discuss const propagation elsewhere. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Lokathor
commented
Mar 13, 2019
|
They had a simple and honest misunderstanding about a question that was about compile-time function evaluation. |
This comment was marked as off-topic.
This comment was marked as off-topic.
|
And then instead of clearing up the misunderstanding this derailed into more than 10 posts (and counting) discussing whether const propagation is guaranteed to happen or not, whether it can have adverse side-effects, ... all of which are off-topic. And before this derails into a meta-discussion about this, I'll stop responding on that subject. |
This comment has been minimized.
This comment has been minimized.
|
@rust-lang/lang can we move this to FCP? There has been no (on-topic) discussion that lead to nontrivial changes since a month. All the open questions are documented under the "Unresolved questions" section and should be addressed before stabilization, but should not block implementing the feature unstabily. |
Centril
added
the
I-nominated
label
Mar 26, 2019
This comment has been minimized.
This comment has been minimized.
|
One possible syntax for trait default method bodies being const-capable would be |
This comment was marked as off-topic.
This comment was marked as off-topic.
|
Also, I'm a bit confused about the use of |
This comment was marked as off-topic.
This comment was marked as off-topic.
Lokathor
commented
Mar 28, 2019
|
If it's a const Cell then there's no reason to disallow it. |
This comment was marked as off-topic.
This comment was marked as off-topic.
|
@Lokathor This seems like something we should discuss in a separate issue rather than this one; I can easily see how this would balloon into a long discussion. |
oli-obk commentedFeb 5, 2019
•
edited
TLDR: Allow
and
cc @Centril @varkor @RalfJung @eddyb
This RFC has gone through an extensive pre-RFC phase in rust-rfcs/const-eval#8
Rendered