Remove control_flow_destroyed
and properly lower &&
and ||
This commit is contained in:
parent
66f0cef1b1
commit
f33a75c20c
8 changed files with 0 additions and 77 deletions
|
@ -148,14 +148,6 @@ pub struct Body<'tcx> {
|
||||||
/// Debug information pertaining to user variables, including captures.
|
/// Debug information pertaining to user variables, including captures.
|
||||||
pub var_debug_info: Vec<VarDebugInfo<'tcx>>,
|
pub var_debug_info: Vec<VarDebugInfo<'tcx>>,
|
||||||
|
|
||||||
/// Mark this MIR of a const context other than const functions as having converted a `&&` or
|
|
||||||
/// `||` expression into `&` or `|` respectively. This is problematic because if we ever stop
|
|
||||||
/// this conversion from happening and use short circuiting, we will cause the following code
|
|
||||||
/// to change the value of `x`: `let mut x = 42; false && { x = 55; true };`
|
|
||||||
///
|
|
||||||
/// List of places where control flow was destroyed. Used for error reporting.
|
|
||||||
pub control_flow_destroyed: Vec<(Span, String)>,
|
|
||||||
|
|
||||||
/// A span representing this MIR, for error reporting.
|
/// A span representing this MIR, for error reporting.
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
|
||||||
|
@ -185,7 +177,6 @@ impl<'tcx> Body<'tcx> {
|
||||||
arg_count: usize,
|
arg_count: usize,
|
||||||
var_debug_info: Vec<VarDebugInfo<'tcx>>,
|
var_debug_info: Vec<VarDebugInfo<'tcx>>,
|
||||||
span: Span,
|
span: Span,
|
||||||
control_flow_destroyed: Vec<(Span, String)>,
|
|
||||||
generator_kind: Option<GeneratorKind>,
|
generator_kind: Option<GeneratorKind>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// We need `arg_count` locals, and one for the return place.
|
// We need `arg_count` locals, and one for the return place.
|
||||||
|
@ -212,7 +203,6 @@ impl<'tcx> Body<'tcx> {
|
||||||
span,
|
span,
|
||||||
required_consts: Vec::new(),
|
required_consts: Vec::new(),
|
||||||
ignore_interior_mut_in_const_validation: false,
|
ignore_interior_mut_in_const_validation: false,
|
||||||
control_flow_destroyed,
|
|
||||||
predecessor_cache: PredecessorCache::new(),
|
predecessor_cache: PredecessorCache::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +226,6 @@ impl<'tcx> Body<'tcx> {
|
||||||
spread_arg: None,
|
spread_arg: None,
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
required_consts: Vec::new(),
|
required_consts: Vec::new(),
|
||||||
control_flow_destroyed: Vec::new(),
|
|
||||||
generator_kind: None,
|
generator_kind: None,
|
||||||
var_debug_info: Vec::new(),
|
var_debug_info: Vec::new(),
|
||||||
ignore_interior_mut_in_const_validation: false,
|
ignore_interior_mut_in_const_validation: false,
|
||||||
|
|
|
@ -251,7 +251,6 @@ fn new_body<'tcx>(
|
||||||
arg_count,
|
arg_count,
|
||||||
vec![],
|
vec![],
|
||||||
span,
|
span,
|
||||||
vec![],
|
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,8 +207,6 @@ impl Validator<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
check_short_circuiting_in_const_local(self.ccx);
|
|
||||||
|
|
||||||
if body.is_cfg_cyclic() {
|
if body.is_cfg_cyclic() {
|
||||||
// We can't provide a good span for the error here, but this should be caught by the
|
// We can't provide a good span for the error here, but this should be caught by the
|
||||||
// HIR const-checker anyways.
|
// HIR const-checker anyways.
|
||||||
|
@ -626,44 +624,6 @@ fn error_min_const_fn_violation(tcx: TyCtxt<'_>, span: Span, msg: Cow<'_, str>)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_short_circuiting_in_const_local(ccx: &ConstCx<'_, 'tcx>) {
|
|
||||||
let body = ccx.body;
|
|
||||||
|
|
||||||
if body.control_flow_destroyed.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut locals = body.vars_iter();
|
|
||||||
if let Some(local) = locals.next() {
|
|
||||||
let span = body.local_decls[local].source_info.span;
|
|
||||||
let mut error = ccx.tcx.sess.struct_span_err(
|
|
||||||
span,
|
|
||||||
&format!(
|
|
||||||
"new features like let bindings are not permitted in {}s \
|
|
||||||
which also use short circuiting operators",
|
|
||||||
ccx.const_kind(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
for (span, kind) in body.control_flow_destroyed.iter() {
|
|
||||||
error.span_note(
|
|
||||||
*span,
|
|
||||||
&format!(
|
|
||||||
"use of {} here does not actually short circuit due to \
|
|
||||||
the const evaluator presently not being able to do control flow. \
|
|
||||||
See issue #49146 <https://github.com/rust-lang/rust/issues/49146> \
|
|
||||||
for more information.",
|
|
||||||
kind
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for local in locals {
|
|
||||||
let span = body.local_decls[local].source_info.span;
|
|
||||||
error.span_note(span, "more locals are defined here");
|
|
||||||
}
|
|
||||||
error.emit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_return_ty_is_sync(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, hir_id: HirId) {
|
fn check_return_ty_is_sync(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, hir_id: HirId) {
|
||||||
let ty = body.return_ty();
|
let ty = body.return_ty();
|
||||||
tcx.infer_ctxt().enter(|infcx| {
|
tcx.infer_ctxt().enter(|infcx| {
|
||||||
|
|
|
@ -133,7 +133,6 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
|
||||||
body.arg_count,
|
body.arg_count,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
tcx.def_span(source.def_id()),
|
tcx.def_span(source.def_id()),
|
||||||
Default::default(),
|
|
||||||
body.generator_kind,
|
body.generator_kind,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1142,7 +1142,6 @@ pub fn promote_candidates<'tcx>(
|
||||||
0,
|
0,
|
||||||
vec![],
|
vec![],
|
||||||
body.span,
|
body.span,
|
||||||
vec![],
|
|
||||||
body.generator_kind,
|
body.generator_kind,
|
||||||
);
|
);
|
||||||
promoted.ignore_interior_mut_in_const_validation = true;
|
promoted.ignore_interior_mut_in_const_validation = true;
|
||||||
|
|
|
@ -778,7 +778,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
self.arg_count,
|
self.arg_count,
|
||||||
self.var_debug_info,
|
self.var_debug_info,
|
||||||
self.fn_span,
|
self.fn_span,
|
||||||
self.hir.control_flow_destroyed(),
|
|
||||||
self.generator_kind,
|
self.generator_kind,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,20 +255,6 @@ fn make_mirror_unadjusted<'a, 'tcx>(
|
||||||
} else {
|
} else {
|
||||||
// FIXME overflow
|
// FIXME overflow
|
||||||
match (op.node, cx.constness) {
|
match (op.node, cx.constness) {
|
||||||
// Destroy control flow if `#![feature(const_if_match)]` is not enabled.
|
|
||||||
(hir::BinOpKind::And, hir::Constness::Const)
|
|
||||||
if !cx.tcx.features().const_if_match =>
|
|
||||||
{
|
|
||||||
cx.control_flow_destroyed.push((op.span, "`&&` operator".into()));
|
|
||||||
ExprKind::Binary { op: BinOp::BitAnd, lhs: lhs.to_ref(), rhs: rhs.to_ref() }
|
|
||||||
}
|
|
||||||
(hir::BinOpKind::Or, hir::Constness::Const)
|
|
||||||
if !cx.tcx.features().const_if_match =>
|
|
||||||
{
|
|
||||||
cx.control_flow_destroyed.push((op.span, "`||` operator".into()));
|
|
||||||
ExprKind::Binary { op: BinOp::BitOr, lhs: lhs.to_ref(), rhs: rhs.to_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
(hir::BinOpKind::And, _) => ExprKind::LogicalOp {
|
(hir::BinOpKind::And, _) => ExprKind::LogicalOp {
|
||||||
op: LogicalOp::And,
|
op: LogicalOp::And,
|
||||||
lhs: lhs.to_ref(),
|
lhs: lhs.to_ref(),
|
||||||
|
|
|
@ -47,9 +47,6 @@ crate struct Cx<'a, 'tcx> {
|
||||||
|
|
||||||
/// Whether this constant/function needs overflow checks.
|
/// Whether this constant/function needs overflow checks.
|
||||||
check_overflow: bool,
|
check_overflow: bool,
|
||||||
|
|
||||||
/// See field with the same name on `mir::Body`.
|
|
||||||
control_flow_destroyed: Vec<(Span, String)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Cx<'a, 'tcx> {
|
impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||||
|
@ -89,13 +86,8 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||||
body_owner: src_def_id.to_def_id(),
|
body_owner: src_def_id.to_def_id(),
|
||||||
body_owner_kind,
|
body_owner_kind,
|
||||||
check_overflow,
|
check_overflow,
|
||||||
control_flow_destroyed: Vec::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn control_flow_destroyed(self) -> Vec<(Span, String)> {
|
|
||||||
self.control_flow_destroyed
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Cx<'a, 'tcx> {
|
impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue