-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Allow let bindings and destructuring in constants and const fn #49172
Conversation
@@ -120,7 +120,7 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { | |||
rpo: ReversePostorder<'a, 'tcx>, | |||
tcx: TyCtxt<'a, 'gcx, 'tcx>, | |||
param_env: ty::ParamEnv<'tcx>, | |||
temp_qualif: IndexVec<Local, Option<Qualif>>, | |||
local_qualif: IndexVec<Local, Option<Qualif>>, | |||
return_qualif: Option<Qualif>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move this into local_qualif
?
@@ -189,8 +189,16 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { | |||
|
|||
/// Error about extra statements in a constant. | |||
fn statement_like(&mut self) { | |||
if self.tcx.sess.features_untracked().const_let { | |||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems bad, because statement_like
is used for a lot of errors - it should maybe be split into several functions?
self.tcx.sess.features_untracked().const_let => { | ||
debug!("store to var {:?}", index); | ||
match self.local_qualif[index] { | ||
Some(ref mut qualif) => *qualif &= self.qualif, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you want to replace the qualif
always (e.g. let mut x = None; x = Some(TypeThatNeedsDrop);
).
Also, if you have this special case, why do you need to do anything about statement_like
?
@@ -678,6 +700,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { | |||
self.add(Qualif::STATIC_REF); | |||
} | |||
|
|||
if self.mode == Mode::ConstFn && self.tcx.sess.features_untracked().const_let { | |||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is bad because it breaks promotion in const fn
. Also, you want mutable borrows to locals outside of const fn
too, right? I think we should orthogonally allow &mut foo
in regular static
, so only const
needs a special-case at the outermost level (and promotion also needs to keep disallowing &mut NotZST
).
@oli-obk If you want to get this merged quickly, I'd suggest dropping the borrowing changes. cc @nikomatsakis A bit of a conundrum: But we do want to allow |
I removed the borrowing changes |
Ping from triage, @eddyb ! |
This is very low priority atm. We could close it until after the next beta cut. |
Ping from triage @eddyb! This PR needs your review. |
Ping from triage! Can @eddyb or someone else from @rust-lang/compiler review this? |
@@ -1058,6 +1078,11 @@ This does not pose a problem by itself because they can't be accessed directly." | |||
// Avoid a generic error for other uses of arguments. | |||
if self.qualif.intersects(Qualif::FN_ARGUMENT) { | |||
let decl = &self.mir.local_decls[index]; | |||
if decl.source_info.span.allows_unstable() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this condition flipped? EDIT: this appears to be the same for all allows_unstable
.
@@ -355,10 +365,13 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { | |||
TerminatorKind::FalseUnwind { .. } => None, | |||
|
|||
TerminatorKind::Return => { | |||
if self.tcx.sess.features_untracked().const_let { | |||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would instead put an if
around all the code below, just to make sure it's explicit.
Note to self. more tests: // ok
const X: FakeNeedsDrop = { let x = FakeNeedsDrop; x };
// error
const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x };
// error
const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); } |
Ping from triage @oli-obk ! Any time to work on this in the near future? |
This comment has been minimized.
This comment has been minimized.
Ping from triage @eddyb! This PR needs your review. |
#50603 has been merged. |
amazingly there are no conflicts whatsoever. @eddyb this is ready for another review |
} | ||
Place::Local(index) if self.mir.local_kind(index) == LocalKind::ReturnPointer => { | ||
debug!("store to return place {:?}", index); | ||
store(&mut self.return_qualif) | ||
store(&mut self.local_qualif[RETURN_PLACE]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you combine these two match arms?
r=me with the nit fixed |
@bors r=eddyb |
📌 Commit 2483c81 has been approved by |
☀️ Test successful - status-appveyor, status-travis |
This PR needs to be backported to beta in order to backport #50909. cc @rust-lang/compiler |
i can create a version of #50909 that doesn't depend on this, it's just a debug statement that conflicts |
@oli-obk that would be awesome! |
r? @eddyb
cc #48821