Skip to content

Commit 83bbd18

Browse files
committed
Introduce enhanced_binary_op feature
1 parent 5e57faa commit 83bbd18

File tree

5 files changed

+73
-18
lines changed

5 files changed

+73
-18
lines changed

compiler/rustc_feature/src/active.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ declare_features! (
142142
(active, allow_internal_unstable, "1.0.0", None, None),
143143
/// Allows identifying the `compiler_builtins` crate.
144144
(active, compiler_builtins, "1.13.0", None, None),
145+
/// Allows more code to compile within a binary operation context
146+
(active, enhanced_binary_op, "1.60.0", None, None),
145147
/// Allows using the `rust-intrinsic`'s "ABI".
146148
(active, intrinsics, "1.0.0", None, None),
147149
/// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.

compiler/rustc_mir_build/src/build/expr/into.rs

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -153,27 +153,51 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
153153
//
154154
// [block: If(lhs)] -true-> [else_block: dest = (rhs)]
155155
// | (false)
156-
// [shortcurcuit_block: dest = false]
156+
// [shortcircuit_block: dest = false]
157157
//
158158
// Or:
159159
//
160160
// [block: If(lhs)] -false-> [else_block: dest = (rhs)]
161161
// | (true)
162-
// [shortcurcuit_block: dest = true]
163-
164-
let (shortcircuit_block, mut else_block, join_block) = (
165-
this.cfg.start_new_block(),
166-
this.cfg.start_new_block(),
167-
this.cfg.start_new_block(),
168-
);
169-
170-
let lhs = unpack!(block = this.as_local_operand(block, &this.thir[lhs]));
171-
let blocks = match op {
172-
LogicalOp::And => (else_block, shortcircuit_block),
173-
LogicalOp::Or => (shortcircuit_block, else_block),
174-
};
175-
let term = TerminatorKind::if_(this.tcx, lhs, blocks.0, blocks.1);
176-
this.cfg.terminate(block, source_info, term);
162+
// [shortcircuit_block: dest = true]
163+
164+
let (shortcircuit_block, mut else_block, join_block) =
165+
if this.tcx.features().enhanced_binary_op {
166+
let local_scope = this.local_scope();
167+
168+
let blocks = this.in_if_then_scope(local_scope, |this| {
169+
this.then_else_break(
170+
block,
171+
&this.thir[lhs],
172+
Some(local_scope),
173+
local_scope,
174+
this.thir[lhs].span,
175+
)
176+
});
177+
178+
let (shortcircuit_block, else_block) = match op {
179+
LogicalOp::And => (blocks.1, blocks.0),
180+
LogicalOp::Or => (blocks.0, blocks.1),
181+
};
182+
183+
(shortcircuit_block, else_block, this.cfg.start_new_block())
184+
} else {
185+
let (shortcircuit_block, else_block, join_block) = (
186+
this.cfg.start_new_block(),
187+
this.cfg.start_new_block(),
188+
this.cfg.start_new_block(),
189+
);
190+
191+
let lhs = unpack!(block = this.as_local_operand(block, &this.thir[lhs]));
192+
let blocks = match op {
193+
LogicalOp::And => (else_block, shortcircuit_block),
194+
LogicalOp::Or => (shortcircuit_block, else_block),
195+
};
196+
let term = TerminatorKind::if_(this.tcx, lhs, blocks.0, blocks.1);
197+
this.cfg.terminate(block, source_info, term);
198+
199+
(shortcircuit_block, else_block, join_block)
200+
};
177201

178202
this.cfg.push_assign_constant(
179203
shortcircuit_block,
@@ -188,12 +212,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
188212
},
189213
},
190214
);
191-
this.cfg.goto(shortcircuit_block, source_info, join_block);
192215

193216
let rhs = unpack!(else_block = this.as_local_operand(else_block, &this.thir[rhs]));
194217
this.cfg.push_assign(else_block, source_info, destination, Rvalue::Use(rhs));
218+
this.cfg.goto(shortcircuit_block, source_info, join_block);
195219
this.cfg.goto(else_block, source_info, join_block);
196-
197220
join_block.unit()
198221
}
199222
ExprKind::Loop { body } => {

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ symbols! {
611611
enclosing_scope,
612612
encode,
613613
end,
614+
enhanced_binary_op,
614615
env,
615616
env_macro,
616617
eprint_macro,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#![feature(enhanced_binary_op)]
2+
3+
fn and_chain() {
4+
let z;
5+
if true && { z = 3; true } && z == 3 {}
6+
}
7+
8+
fn and_chain_2() {
9+
let z;
10+
true && { z = 3; true } && z == 3;
11+
}
12+
13+
fn or_chain() {
14+
let z;
15+
if false || { z = 3; false } || z == 3 {}
16+
//~^ ERROR use of possibly-uninitialized
17+
}
18+
19+
fn main() {
20+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0381]: use of possibly-uninitialized variable: `z`
2+
--> $DIR/feature-gate-enhanced_binary_op.rs:15:37
3+
|
4+
LL | if false || { z = 3; false } || z == 3 {}
5+
| ^ use of possibly-uninitialized `z`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0381`.

0 commit comments

Comments
 (0)