Uh oh!
There was an error while loading. Please reload this page.
Use explicit promotion for constants in repeat expressions - #70042
Use explicit promotion for constants in repeat expressions#70042oli-obk wants to merge 9 commits into
Conversation
This comment has been minimized.
This comment has been minimized.
oli-obk
commented
Mar 16, 2020
r? @RalfJung I guess? |
This comment has been minimized.
This comment has been minimized.
Uh oh!
There was an error while loading. Please reload this page.
RalfJung
commented
Mar 18, 2020
Uh, I don't actually understand most of the code you are touching here -- the glue code that connects const-eval with the rest of the compiler. I could rubber-stamp it as it looks simple enough, but maybe we can think of someone who can do a meaningful review? @eddyb? (They have a lot on their plate though.) However, taking a step back... this is actually a pretty big decision, I feel. Last time we talked, it was still the case that rustc first checked if the repeat expression could be promoted, and only if that failed, it checked the And even with that principle upheld, there is still the issue that it might be hard to predict whether this code runs at run-time or at compile-time (because that depends on whether the
That doesn't have to happen here, it could be part of a stabilization FCP, but it should come up explicitly. |
oli-obk
commented
Mar 18, 2020
I am working on a prototype for this since a few days, it seems like something we want independently of this PR |
oli-obk
commented
Mar 18, 2020
This is exactly what this PR does (and what it was doing with implicit promo. If the type is
I believe we are already testing it, but I can add comments to those tests so if some day in the future something changes there, ppl know what we want to happen.
We can probably make the codegen code around |
This PR doesn't change the order in which Back then I was first told
I feel it would be more direct and more local to have a |
Uh oh!
There was an error while loading. Please reload this page.
oli-obk
commented
Mar 18, 2020
Oh that makes a lot of sense. Let's do that (or just report the tailored error right there) |
Uh oh!
There was an error while loading. Please reload this page.
9f751fe to
0ded830Compare…g had content there before the current changes
This renaming was already done in some modules via import renaming. It's strictly used as a context, and it contains a `TyCtxt`.
0ded830 to
a4e551eCompareoli-obk
commented
Apr 2, 2020
r? @eddyb I split the PR into commits where each commit passes tests. The last commit (the only one actually changing any behavior) is now super small. |
eddyb
left a comment
There was a problem hiding this comment.
r=me on the changes themselves, but I don't know if we want to land the last commit without some process? I don't remember what the status of this was, did we decide already?
oli-obk
commented
Apr 2, 2020
@Centril does this need an FCP or is an FCP for stabilization at some point enough? |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| let is_promotable = validator.validate_candidate(candidate).is_ok(); | ||
| if validator.explicit && !is_promotable { | ||
| ccx.tcx.sess.delay_span_bug( |
There was a problem hiding this comment.
Could you add a comment explaining why this check is absolutely important?
I want to be sure someone doesn't just remove it when it seems convenient.^^
The explicit field's doc comment already says a few things, so here's a proposal:
// If we use explicit validation, we carry the risk of turning a legitimate run-time
// operation into a failing compile-time operation. Make sure that does not happen
// by asserting that there is no possible run-time behavior here in case promotion fails.
There was a problem hiding this comment.
What actually happens is not that we turn it into a failing compile-time op, it's that we don't promote at all, thus keeping the runtime operation, which happened to be the right thing in the cases that the assertion caught.
There was a problem hiding this comment.
keeping the runtime operation
We do that because we don't even try. But the branch here is for after we tried, so we cannot be in the case where we want to keep the runtime operation.
There was a problem hiding this comment.
Yes we are, this checks whether we can promote and if not, we remove it from the list. Then we process this list in promote_candidates, which can only fail to promote without ICEing in case of nested promotion candidates, where promoting one candidate eliminated the other candidate because the other candidate is part of the already promoted one.
There was a problem hiding this comment.
I am entirely confused now.
Going back a step -- did you want to say above that my proposed comment was incorrect, and suggest a better one? I don't understand what is is you are trying to say here.
There was a problem hiding this comment.
Yes, I believe your comment is incorrect
// If we use explicit validation, we expect promotion to succeed.
// If an explicit promotion candidate were to get "unpromoted" here,
// that means we keep an operation that we expect to happen at compile-time
// at runtime. In case of repeat elements, this would just cause an error
// later in compilation (due to multiple moves out of a `!Copy` value), but
// for `rustc_arg_required_const` function arguments, where a constant is
// required, ending up with a runtime value would likely ICE the compiler
// during codegen, or silently cause undocumented and undesired LLVM features
// to be used.
There was a problem hiding this comment.
@RalfJung What do you think about the above comment?
There was a problem hiding this comment.
I think we are having different views of the same thing here.
Re: your comment, I am not worried about the case where, if promotion analysis here fails, we ICE the compiler later. I am worried about the case where we do not ICE later. Because that means that, no matter whether promotion succeeds or fails, we produce a program, but the programs may do different things because we use the less conservative, "explicit promotion" rules. That is what I think this comment should explain.
There was a problem hiding this comment.
(This is the delay_span_bug that I meant in my other comment, that we should add nevertheless.)
This comment has been minimized.
This comment has been minimized.
Centril
commented
Apr 7, 2020
The PR feels too much in-flux for me to say one way or another. A summary with the rationale, pros, and cons would be helpful. |
This PR changes our behaviour in repeat expressions, turning the repeat element into a full (anonymous) constant if the type is constFOO:Vec<i32> = Vec::new();[FOO;42]because the repeat element was using the rules for promoteds instead of those for constants. @scottmcm worries that
source: #49147 (comment) Additionally on the tracking issue @RalfJung worried (#49147 (comment)) that it may be suprising to users as to what code is accepted and what isn't, since the This change is forward compatible with #49147 (comment) which suggests to permit |
This comment has been minimized.
This comment has been minimized.
Uh oh!
There was an error while loading. Please reload this page.
19b3239 to
d41c8d3Compare| let n = n.try_eval_usize(self.ccx.tcx, self.ccx.param_env); | ||
| let length_requires_copy_or_promotion = match n { | ||
| // Unevaluable (e.g. too generic) -> assume > 1. | ||
| None => true, |
There was a problem hiding this comment.
So could this lead to a problem if we later figure out that actually, the constant is1, and then we compile the program after a failed attempt to explicitly promote? (That would trigger the delayed_span_bug now.)
There was a problem hiding this comment.
the alternative is to fail to compile (!Copy types treat generic lengths as > 1, so if it later happens to be 1 that's irrelevant). While we could permit that, we'd be adding a new source of post monomorphization errors.
There was a problem hiding this comment.
I mean I am fine with this as long as it is guaranteed that this cannot ICE due to the safety net delay_span_bug this PR also adds.
I want to be sure that we do not draw ourselves into a corner where, or backwards compatibility reasons, we have to remove that safety net to fix an ICE.
Centril
commented
Apr 10, 2020
We discussed this at Thursday's language team meeting (2020-04-09). Due to nervousness regarding extending promotion to more places, the rough consensus of those present at the meeting were that we should first consider something like We'll also add a checkbox to the tracking issue #49147 to make sure that we consider whether |
RalfJung
commented
Apr 16, 2020
@oli-obk at least the |
RalfJung
commented
Apr 16, 2020
#71198 is that follow-up. Thanks! |
…Jung Const check/promotion cleanup and sanity assertion r? @RalfJung This is just the part of rust-lang#70042 (comment) that does not change behaviour
…Jung Const check/promotion cleanup and sanity assertion r? @RalfJung This is just the part of rust-lang#70042 (comment) that does not change behaviour
As per #49147 (comment)
cc @rust-lang/wg-const-eval