Skip to content

Commit

Permalink
Introduce enhanced_binary_op feature
Browse files Browse the repository at this point in the history
  • Loading branch information
c410-f3r committed Jan 19, 2022
1 parent 5e57faa commit 83bbd18
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 18 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ declare_features! (
(active, allow_internal_unstable, "1.0.0", None, None),
/// Allows identifying the `compiler_builtins` crate.
(active, compiler_builtins, "1.13.0", None, None),
/// Allows more code to compile within a binary operation context
(active, enhanced_binary_op, "1.60.0", None, None),
/// Allows using the `rust-intrinsic`'s "ABI".
(active, intrinsics, "1.0.0", None, None),
/// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
Expand Down
59 changes: 41 additions & 18 deletions compiler/rustc_mir_build/src/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,27 +153,51 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
//
// [block: If(lhs)] -true-> [else_block: dest = (rhs)]
// | (false)
// [shortcurcuit_block: dest = false]
// [shortcircuit_block: dest = false]
//
// Or:
//
// [block: If(lhs)] -false-> [else_block: dest = (rhs)]
// | (true)
// [shortcurcuit_block: dest = true]

let (shortcircuit_block, mut else_block, join_block) = (
this.cfg.start_new_block(),
this.cfg.start_new_block(),
this.cfg.start_new_block(),
);

let lhs = unpack!(block = this.as_local_operand(block, &this.thir[lhs]));
let blocks = match op {
LogicalOp::And => (else_block, shortcircuit_block),
LogicalOp::Or => (shortcircuit_block, else_block),
};
let term = TerminatorKind::if_(this.tcx, lhs, blocks.0, blocks.1);
this.cfg.terminate(block, source_info, term);
// [shortcircuit_block: dest = true]

let (shortcircuit_block, mut else_block, join_block) =
if this.tcx.features().enhanced_binary_op {
let local_scope = this.local_scope();

let blocks = this.in_if_then_scope(local_scope, |this| {
this.then_else_break(
block,
&this.thir[lhs],
Some(local_scope),
local_scope,
this.thir[lhs].span,
)
});

let (shortcircuit_block, else_block) = match op {
LogicalOp::And => (blocks.1, blocks.0),
LogicalOp::Or => (blocks.0, blocks.1),
};

(shortcircuit_block, else_block, this.cfg.start_new_block())
} else {
let (shortcircuit_block, else_block, join_block) = (
this.cfg.start_new_block(),
this.cfg.start_new_block(),
this.cfg.start_new_block(),
);

let lhs = unpack!(block = this.as_local_operand(block, &this.thir[lhs]));
let blocks = match op {
LogicalOp::And => (else_block, shortcircuit_block),
LogicalOp::Or => (shortcircuit_block, else_block),
};
let term = TerminatorKind::if_(this.tcx, lhs, blocks.0, blocks.1);
this.cfg.terminate(block, source_info, term);

(shortcircuit_block, else_block, join_block)
};

this.cfg.push_assign_constant(
shortcircuit_block,
Expand All @@ -188,12 +212,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
},
},
);
this.cfg.goto(shortcircuit_block, source_info, join_block);

let rhs = unpack!(else_block = this.as_local_operand(else_block, &this.thir[rhs]));
this.cfg.push_assign(else_block, source_info, destination, Rvalue::Use(rhs));
this.cfg.goto(shortcircuit_block, source_info, join_block);
this.cfg.goto(else_block, source_info, join_block);

join_block.unit()
}
ExprKind::Loop { body } => {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@ symbols! {
enclosing_scope,
encode,
end,
enhanced_binary_op,
env,
env_macro,
eprint_macro,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#![feature(enhanced_binary_op)]

fn and_chain() {
let z;
if true && { z = 3; true } && z == 3 {}
}

fn and_chain_2() {
let z;
true && { z = 3; true } && z == 3;
}

fn or_chain() {
let z;
if false || { z = 3; false } || z == 3 {}
//~^ ERROR use of possibly-uninitialized
}

fn main() {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0381]: use of possibly-uninitialized variable: `z`
--> $DIR/feature-gate-enhanced_binary_op.rs:15:37
|
LL | if false || { z = 3; false } || z == 3 {}
| ^ use of possibly-uninitialized `z`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0381`.

0 comments on commit 83bbd18

Please sign in to comment.