Skip to content

Commit d62bcad

Browse files
committed
Allow let bindings everywhere
1 parent 7ec3c10 commit d62bcad

File tree

76 files changed

+446
-692
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+446
-692
lines changed

src/librustc/mir/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ pub struct Mir<'tcx> {
149149
/// This is used for the "rust-call" ABI.
150150
pub spread_arg: Option<Local>,
151151

152+
/// Mark this MIR of a const context other than const functions as having converted a `&&` or
153+
/// `||` expression into `&` or `|` respectively. This is problematic because if we ever stop
154+
/// this conversion from happening and use short circuiting, we will cause the following code
155+
/// to change the value of `x`: `let mut x = 42; false && { x = 55; true };`
156+
pub const_can_have_let_mut_bindings: bool,
157+
152158
/// A span representing this MIR, for error reporting
153159
pub span: Span,
154160

@@ -167,6 +173,7 @@ impl<'tcx> Mir<'tcx> {
167173
arg_count: usize,
168174
upvar_decls: Vec<UpvarDecl>,
169175
span: Span,
176+
const_can_have_let_mut_bindings: bool,
170177
) -> Self {
171178
// We need `arg_count` locals, and one for the return place
172179
assert!(
@@ -191,6 +198,7 @@ impl<'tcx> Mir<'tcx> {
191198
spread_arg: None,
192199
span,
193200
cache: cache::Cache::new(),
201+
const_can_have_let_mut_bindings,
194202
}
195203
}
196204

@@ -421,6 +429,7 @@ impl_stable_hash_for!(struct Mir<'tcx> {
421429
arg_count,
422430
upvar_decls,
423431
spread_arg,
432+
const_can_have_let_mut_bindings,
424433
span,
425434
cache
426435
});
@@ -2974,6 +2983,7 @@ BraceStructTypeFoldableImpl! {
29742983
arg_count,
29752984
upvar_decls,
29762985
spread_arg,
2986+
const_can_have_let_mut_bindings,
29772987
span,
29782988
cache,
29792989
}

src/librustc_mir/build/mod.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -854,15 +854,17 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
854854
}
855855
}
856856

857-
Mir::new(self.cfg.basic_blocks,
858-
self.source_scopes,
859-
ClearCrossCrate::Set(self.source_scope_local_data),
860-
IndexVec::new(),
861-
yield_ty,
862-
self.local_decls,
863-
self.arg_count,
864-
self.upvar_decls,
865-
self.fn_span
857+
Mir::new(
858+
self.cfg.basic_blocks,
859+
self.source_scopes,
860+
ClearCrossCrate::Set(self.source_scope_local_data),
861+
IndexVec::new(),
862+
yield_ty,
863+
self.local_decls,
864+
self.arg_count,
865+
self.upvar_decls,
866+
self.fn_span,
867+
self.hir.const_can_have_let_mut_bindings(),
866868
)
867869
}
868870

src/librustc_mir/hair/cx/expr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,13 +372,15 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
372372
// FIXME(eddyb) use logical ops in constants when
373373
// they can handle that kind of control-flow.
374374
(hir::BinOpKind::And, hir::Constness::Const) => {
375+
cx.const_can_have_let_mut_bindings = false;
375376
ExprKind::Binary {
376377
op: BinOp::BitAnd,
377378
lhs: lhs.to_ref(),
378379
rhs: rhs.to_ref(),
379380
}
380381
}
381382
(hir::BinOpKind::Or, hir::Constness::Const) => {
383+
cx.const_can_have_let_mut_bindings = false;
382384
ExprKind::Binary {
383385
op: BinOp::BitOr,
384386
lhs: lhs.to_ref(),

src/librustc_mir/hair/cx/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
5656

5757
/// True if this constant/function needs overflow checks.
5858
check_overflow: bool,
59+
60+
/// See field with the same name on `Mir`
61+
const_can_have_let_mut_bindings: bool,
5962
}
6063

6164
impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
@@ -96,9 +99,13 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
9699
constness,
97100
body_owner_kind,
98101
check_overflow,
102+
const_can_have_let_mut_bindings: true,
99103
}
100104
}
101105

106+
pub fn const_can_have_let_mut_bindings(&self) -> bool {
107+
self.const_can_have_let_mut_bindings
108+
}
102109
}
103110

104111
impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {

src/librustc_mir/shim.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
219219
local_decls_for_sig(&sig, span),
220220
sig.inputs().len(),
221221
vec![],
222-
span
222+
span,
223+
true,
223224
);
224225

225226
if let Some(..) = ty {
@@ -387,7 +388,8 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
387388
self.local_decls,
388389
self.sig.inputs().len(),
389390
vec![],
390-
self.span
391+
self.span,
392+
true,
391393
)
392394
}
393395

@@ -835,7 +837,8 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
835837
local_decls,
836838
sig.inputs().len(),
837839
vec![],
838-
span
840+
span,
841+
true,
839842
);
840843
if let Abi::RustCall = sig.abi {
841844
mir.spread_arg = Some(Local::new(sig.inputs().len()));
@@ -912,6 +915,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
912915
local_decls,
913916
sig.inputs().len(),
914917
vec![],
915-
span
918+
span,
919+
true,
916920
)
917921
}

src/librustc_mir/transform/promote_consts.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,8 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
412412
initial_locals,
413413
0,
414414
vec![],
415-
mir.span
415+
mir.span,
416+
false,
416417
),
417418
tcx,
418419
source: mir,

0 commit comments

Comments
 (0)