Skip to content
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

Fix various aspects around let bindings inside const functions #56160

Merged
merged 25 commits into from
Dec 18, 2018

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Nov 22, 2018

  • forbid let bindings in const contexts that use short circuiting operators
  • harden analysis code against derefs of mutable references

Initially this PR was about stabilizing let bindings, but too many flaws were exposed that need some more testing on nightly

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 22, 2018
@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

Copy link
Contributor

@Centril Centril left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, here's a comprehensive run-pass test that would be nice to add: https://gist.github.com/Centril/a8df54dc8ee0b6bf0da46b5fba446acd

src/test/ui/consts/const_let_assign2.rs Outdated Show resolved Hide resolved
src/test/ui/consts/const_let_assign2.rs Outdated Show resolved Hide resolved
src/test/ui/consts/const_let_assign.rs Outdated Show resolved Hide resolved
@Centril Centril added the relnotes Marks issues that should be documented in the release notes of the next release. label Nov 22, 2018
src/libcore/lib.rs Outdated Show resolved Hide resolved
@rust-highfive

This comment has been minimized.

@eddyb
Copy link
Member

eddyb commented Nov 23, 2018

@oli-obk Can we poison the MIR (i.e. add a flag that we set to true) if && or || are found and decide whether to allow const_let based on that?

@Centril
Copy link
Contributor

Centril commented Nov 23, 2018

@oli-obk I remembered one thing now... floating points and assignment ops... we should make sure that they are not stabilized by including a test with all of the assignment ops for f32 & f64. :)

@Centril
Copy link
Contributor

Centril commented Nov 23, 2018

Having reviewed the main tests, I pass on the torch to...
r? @eddyb

also cc @RalfJung and @nikomatsakis

@rust-highfive rust-highfive assigned eddyb and unassigned Centril Nov 23, 2018
@eddyb
Copy link
Member

eddyb commented Nov 23, 2018

@oli-obk Can you add tests for match with a single arm? I expect it to work.

@oli-obk
Copy link
Contributor Author

oli-obk commented Nov 23, 2018

Can we poison the MIR (i.e. add a flag that we set to true) if && or || are found and decide whether to allow const_let based on that?

I had the exact same idea like an hour ago. I guess that means it wasn't a stupid idea

src/librustc/mir/mod.rs Outdated Show resolved Hide resolved
src/libsyntax/feature_gate.rs Outdated Show resolved Hide resolved
src/test/ui/consts/issue-54224.rs Outdated Show resolved Hide resolved
@RalfJung
Copy link
Member

Initial implementation was merged in May: #49172

Based on #56070 (which relaxes some restrictions around assignments, before that PR we only allowed x = 42; not x.y = 42;

These two seem to contradiction each other. Isn't this stabilizing behavior that has not even landed yet?

@oli-obk
Copy link
Contributor Author

oli-obk commented Nov 26, 2018

I'm going to reintroduce the feature gate and let the final version bake a little more in nightly. I don't feel comfortable changing so many things and stabilizing at the same time.

@oli-obk
Copy link
Contributor Author

oli-obk commented Nov 26, 2018

Single match arms lead to constant contains unimplemented expression type currently. (which happens when you call the not_const method, which happens a lot in const qualif)

@eddyb
Copy link
Member

eddyb commented Nov 26, 2018

@oli-obk Maybe because of the Discriminant "fake read"?

@RalfJung
Copy link
Member

Nit all single-arm matches should work, IMO. Just things like match foo { x => ... }, where there is no pattern. Those should not have a Discriminant "fake read", there might not even be an enum involved.

@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@oli-obk oli-obk changed the title Stabilize let bindings inside const functions Fix various aspects around let bindings inside const functions Nov 27, 2018
@@ -320,6 +320,10 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
}
}

fn const_let_allowed(&self) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a great place for a comment =) in particular, documenting the logic behind these rules.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like:


Currently, without a feature gate, let is only allowed in const fn. With a feature gate, it can appear anywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided on not doing this dual-scheme. Instead we're poisoning constants that use short circuiting operators so they can't also have let bindings.

I'll remove the function and move back to checking the feature gate directly

cx.control_flow_destroyed.push((
op.span,
"`&&` operator".into(),
));
ExprKind::Binary {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woah. I don't think I realized we do this sort of conversion.

if context.is_mutating_use() {
this.not_const()
} else {
this.qualif = Qualif::NOT_CONST;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentionally overriding all other Qualif flags? (vs invoking add)? Why is that? Maybe a comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is an accidental leftover from the larger refactorings. I undid the change and added comments

@nikomatsakis
Copy link
Contributor

First round of review -- I'd like to take one more look before r+ and in particular to know the answer to this question

@@ -0,0 +1,26 @@
error: new features like let bindings are not permitted in constant which also use short circuiting operators
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this reads oddly, it should be "in constants" -- i.e., plural

error: new features like let bindings are not permitted in constant which also use short circuiting operators
--> $DIR/const_short_circuit.rs:6:9
|
LL | let mut x = true && false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, I presume we intend this to be temporary? this restriction is very odd and surprising from an end-user point-of-view, I wonder if we can direct people to some kind of roadmap / URL that explains what the heck is going on?

@nikomatsakis
Copy link
Contributor

r=me modulo nits above

@oli-obk
Copy link
Contributor Author

oli-obk commented Dec 18, 2018

@bors r=nikomatsakis

@bors
Copy link
Contributor

bors commented Dec 18, 2018

📌 Commit d815e2b has been approved by nikomatsakis

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 18, 2018
@bors
Copy link
Contributor

bors commented Dec 18, 2018

⌛ Testing commit d815e2b with merge 36b0f367a017ba709a4539a6873344e7ee62e756...

@bors

This comment has been minimized.

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Dec 18, 2018
@rust-highfive

This comment has been minimized.

@oli-obk

This comment has been minimized.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 18, 2018
@bors
Copy link
Contributor

bors commented Dec 18, 2018

⌛ Testing commit d815e2b with merge cb84844...

bors added a commit that referenced this pull request Dec 18, 2018
Fix various aspects around `let` bindings inside const functions

* forbid `let` bindings in const contexts that use short circuiting operators
* harden analysis code against derefs of mutable references

Initially this PR was about stabilizing `let` bindings, but too many flaws were exposed that need some more testing on nightly
@bors
Copy link
Contributor

bors commented Dec 18, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing cb84844 to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants