diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 5e0ab80c6ac9f..4282132ba76ee 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -419,14 +419,6 @@ impl<'hir> LoweringContext<'_, 'hir> { // Lowers a condition (i.e. `cond` in `if cond` or `while cond`), wrapping it in a terminating scope // so that temporaries created in the condition don't live beyond it. fn lower_cond(&mut self, cond: &Expr) -> &'hir hir::Expr<'hir> { - fn has_let_expr(expr: &Expr) -> bool { - match &expr.kind { - ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs), - ExprKind::Let(..) => true, - _ => false, - } - } - // We have to take special care for `let` exprs in the condition, e.g. in // `if let pat = val` or `if foo && let pat = val`, as we _do_ want `val` to live beyond the // condition in this case. @@ -435,9 +427,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // we still wrap them in terminating scopes, e.g. `if foo && let pat = val` essentially // gets transformed into `if { let _t = foo; _t } && let pat = val` match &cond.kind { - ExprKind::Binary(op @ Spanned { node: ast::BinOpKind::And, .. }, lhs, rhs) - if has_let_expr(cond) => - { + ExprKind::Binary(op @ Spanned { node: ast::BinOpKind::And, .. }, lhs, rhs) => { let op = self.lower_binop(*op); let lhs = self.lower_cond(lhs); let rhs = self.lower_cond(rhs); diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs index 455f0df7cd0ad..3a5c0391ab7d3 100644 --- a/src/tools/clippy/clippy_lints/src/booleans.rs +++ b/src/tools/clippy/clippy_lints/src/booleans.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::eq_expr_value; +use clippy_utils::peel_droptemps; use clippy_utils::source::snippet_opt; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; use if_chain::if_chain; @@ -114,6 +115,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> { } fn run(&mut self, e: &'v Expr<'_>) -> Result { + let e = peel_droptemps(e); fn negate(bin_op_kind: BinOpKind) -> Option { match bin_op_kind { BinOpKind::Eq => Some(BinOpKind::Ne), diff --git a/src/tools/clippy/clippy_lints/src/operators/mod.rs b/src/tools/clippy/clippy_lints/src/operators/mod.rs index 19599731bd6ef..a729e69a8a4c7 100644 --- a/src/tools/clippy/clippy_lints/src/operators/mod.rs +++ b/src/tools/clippy/clippy_lints/src/operators/mod.rs @@ -23,6 +23,7 @@ mod verbose_bit_mask; pub(crate) mod arithmetic_side_effects; +use clippy_utils::peel_droptemps; use rustc_hir::{Body, Expr, ExprKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; @@ -825,6 +826,8 @@ impl<'tcx> LateLintPass<'tcx> for Operators { eq_op::check_assert(cx, e); match e.kind { ExprKind::Binary(op, lhs, rhs) => { + let lhs = peel_droptemps(lhs); + let rhs = peel_droptemps(rhs); if !e.span.from_expansion() { absurd_extreme_comparisons::check(cx, e, op.node, lhs, rhs); if !(macro_with_not_op(lhs) || macro_with_not_op(rhs)) { diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index 377d3fb6f4e1c..d451b30326fcb 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::higher; +use clippy_utils::peel_droptemps; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{path_to_local, usage::is_potentially_mutated}; use if_chain::if_chain; @@ -142,6 +143,7 @@ fn collect_unwrap_info<'tcx>( is_type_diagnostic_item(cx, ty, sym::Result) && ["is_ok", "is_err"].contains(&method_name) } + let expr = peel_droptemps(expr); if let ExprKind::Binary(op, left, right) = &expr.kind { match (invert, op.node) { (false, BinOpKind::And | BinOpKind::BitAnd) | (true, BinOpKind::Or | BinOpKind::BitOr) => { diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 8075881e3bb9d..6bde286adeccc 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -375,6 +375,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { }, ExprKind::Index(arr, index) => self.index(arr, index), ExprKind::AddrOf(_, _, inner) => self.expr(inner).map(|r| Constant::Ref(Box::new(r))), + ExprKind::DropTemps(e) => self.expr(e), // TODO: add other expressions. _ => None, } diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs index a61e4c380886d..9bb08d92a7315 100644 --- a/src/tools/clippy/clippy_utils/src/higher.rs +++ b/src/tools/clippy/clippy_utils/src/higher.rs @@ -4,13 +4,13 @@ use crate::consts::{constant_simple, Constant}; use crate::ty::is_type_diagnostic_item; -use crate::{is_expn_of, match_def_path, paths}; +use crate::{is_expn_of, match_def_path, paths, peel_droptemps}; use if_chain::if_chain; use rustc_ast::ast; use rustc_hir as hir; -use rustc_hir::{Arm, Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath}; +use rustc_hir::{Arm, BinOpKind, Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath}; use rustc_lint::LateContext; -use rustc_span::{sym, symbol, Span}; +use rustc_span::{source_map::Spanned, sym, symbol, Span}; /// The essential nodes of a desugared for loop as well as the entire span: /// `for pat in arg { body }` becomes `(pat, arg, body)`. Return `(pat, arg, body, span)`. @@ -63,20 +63,35 @@ pub struct If<'hir> { pub r#else: Option<&'hir Expr<'hir>>, } +const fn has_let(expr: &Expr<'_>) -> bool { + match expr.kind { + ExprKind::DropTemps(..) => false, + ExprKind::Let(..) => true, + ExprKind::Binary( + Spanned { + node: BinOpKind::And, .. + }, + lhs, + rhs, + ) => has_let(lhs) || has_let(rhs), + _ => panic!("unexpected"), + } +} + impl<'hir> If<'hir> { #[inline] /// Parses an `if` expression pub const fn hir(expr: &Expr<'hir>) -> Option { - if let ExprKind::If( - Expr { - kind: ExprKind::DropTemps(cond), - .. - }, - then, - r#else, - ) = expr.kind - { - Some(Self { cond, then, r#else }) + if let ExprKind::If(cond, then, r#else) = expr.kind { + if !has_let(cond) { + Some(Self { + cond: peel_droptemps(cond), + then, + r#else, + }) + } else { + None + } } else { None } @@ -323,15 +338,7 @@ impl<'hir> While<'hir> { Block { expr: Some(Expr { - kind: - ExprKind::If( - Expr { - kind: ExprKind::DropTemps(condition), - .. - }, - body, - _, - ), + kind: ExprKind::If(cond, body, _), .. }), .. @@ -341,9 +348,18 @@ impl<'hir> While<'hir> { span, ) = expr.kind { - return Some(Self { condition, body, span }); + if !has_let(cond) { + Some(Self { + condition: peel_droptemps(cond), + body, + span, + }) + } else { + None + } + } else { + None } - None } } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 964104fc31d0e..d7d581b009032 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1388,6 +1388,13 @@ pub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> { } } +pub const fn peel_droptemps<'a>(expr: &'a Expr<'a>) -> &'a Expr<'a> { + match expr.kind { + ExprKind::DropTemps(source) => peel_droptemps(source), + _ => expr, + } +} + /// Removes blocks around an expression, only if the block contains just one expression /// and no statements. Unsafe blocks are not removed. /// diff --git a/tests/mir-opt/building/logical_and_in_conditional.function_from_issue_111583.built.after.mir b/tests/mir-opt/building/logical_and_in_conditional.function_from_issue_111583.built.after.mir new file mode 100644 index 0000000000000..cb29bc2bb2afa --- /dev/null +++ b/tests/mir-opt/building/logical_and_in_conditional.function_from_issue_111583.built.after.mir @@ -0,0 +1,103 @@ +// MIR for `function_from_issue_111583` after built + +fn function_from_issue_111583(_1: f64) -> () { + debug z => _1; // in scope 0 at $DIR/logical_and_in_conditional.rs:+0:31: +0:32 + let mut _0: (); // return place in scope 0 at $DIR/logical_and_in_conditional.rs:+0:39: +0:39 + let _2: u64; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:9: +1:13 + let mut _3: u64; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:16: +1:25 + let mut _5: bool; // in scope 0 at $DIR/logical_and_in_conditional.rs:+3:8: +3:38 + let mut _6: u64; // in scope 0 at $DIR/logical_and_in_conditional.rs:+3:8: +3:33 + let mut _7: u64; // in scope 0 at $DIR/logical_and_in_conditional.rs:+3:8: +3:26 + let mut _8: u64; // in scope 0 at $DIR/logical_and_in_conditional.rs:+3:9: +3:20 + let mut _9: f64; // in scope 0 at $DIR/logical_and_in_conditional.rs:+3:9: +3:10 + let mut _10: u64; // in scope 0 at $DIR/logical_and_in_conditional.rs:+3:29: +3:33 + let mut _11: bool; // in scope 0 at $DIR/logical_and_in_conditional.rs:+3:42: +3:60 + let mut _12: f64; // in scope 0 at $DIR/logical_and_in_conditional.rs:+3:42: +3:52 + let mut _13: f64; // in scope 0 at $DIR/logical_and_in_conditional.rs:+3:42: +3:43 + scope 1 { + debug mask => _2; // in scope 1 at $DIR/logical_and_in_conditional.rs:+1:9: +1:13 + let mut _4: i32; // in scope 1 at $DIR/logical_and_in_conditional.rs:+2:9: +2:16 + scope 2 { + debug ret => _4; // in scope 2 at $DIR/logical_and_in_conditional.rs:+2:9: +2:16 + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:9: +1:13 + StorageLive(_3); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:16: +1:25 + _3 = Shl(const 1_u64, const 38_i32); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:16: +1:25 + _2 = Sub(move _3, const 1_u64); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:16: +1:29 + StorageDead(_3); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:28: +1:29 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:9: +1:13 + StorageLive(_4); // scope 1 at $DIR/logical_and_in_conditional.rs:+2:9: +2:16 + _4 = const 0_i32; // scope 1 at $DIR/logical_and_in_conditional.rs:+2:19: +2:20 + FakeRead(ForLet(None), _4); // scope 1 at $DIR/logical_and_in_conditional.rs:+2:9: +2:16 + StorageLive(_5); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:8: +3:38 + StorageLive(_6); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:8: +3:33 + StorageLive(_7); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:8: +3:26 + StorageLive(_8); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:9: +3:20 + StorageLive(_9); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:9: +3:10 + _9 = _1; // scope 2 at $DIR/logical_and_in_conditional.rs:+3:9: +3:10 + _8 = core::f64::::to_bits(move _9) -> [return: bb1, unwind: bb8]; // scope 2 at $DIR/logical_and_in_conditional.rs:+3:9: +3:20 + // mir::Constant + // + span: $DIR/logical_and_in_conditional.rs:19:11: 19:18 + // + literal: Const { ty: fn(f64) -> u64 {core::f64::::to_bits}, val: Value() } + } + + bb1: { + StorageDead(_9); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:19: +3:20 + _7 = Shr(move _8, const 8_i32); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:8: +3:26 + StorageDead(_8); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:25: +3:26 + StorageLive(_10); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:29: +3:33 + _10 = _2; // scope 2 at $DIR/logical_and_in_conditional.rs:+3:29: +3:33 + _6 = BitAnd(move _7, move _10); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:8: +3:33 + StorageDead(_10); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:32: +3:33 + StorageDead(_7); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:32: +3:33 + _5 = Eq(move _6, const 0_u64); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:8: +3:38 + StorageDead(_6); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:37: +3:38 + switchInt(move _5) -> [0: bb3, otherwise: bb2]; // scope 2 at $DIR/logical_and_in_conditional.rs:+3:8: +3:38 + } + + bb2: { + StorageLive(_11); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:42: +3:60 + StorageLive(_12); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:42: +3:52 + StorageLive(_13); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:42: +3:43 + _13 = _1; // scope 2 at $DIR/logical_and_in_conditional.rs:+3:42: +3:43 + _12 = Rem(move _13, const 0.0625f64); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:42: +3:52 + StorageDead(_13); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:51: +3:52 + _11 = Lt(move _12, const 1.0E-13f64); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:42: +3:60 + StorageDead(_12); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:59: +3:60 + switchInt(move _11) -> [0: bb5, otherwise: bb4]; // scope 2 at $DIR/logical_and_in_conditional.rs:+3:42: +3:60 + } + + bb3: { + goto -> bb6; // scope 2 at $DIR/logical_and_in_conditional.rs:+3:8: +3:38 + } + + bb4: { + _4 = Add(_4, const 1_i32); // scope 2 at $DIR/logical_and_in_conditional.rs:+4:9: +4:17 + _0 = const (); // scope 2 at $DIR/logical_and_in_conditional.rs:+3:61: +5:6 + goto -> bb7; // scope 2 at $DIR/logical_and_in_conditional.rs:+3:5: +5:6 + } + + bb5: { + goto -> bb6; // scope 2 at $DIR/logical_and_in_conditional.rs:+3:42: +3:60 + } + + bb6: { + _0 = const (); // scope 2 at $DIR/logical_and_in_conditional.rs:+5:6: +5:6 + goto -> bb7; // scope 2 at $DIR/logical_and_in_conditional.rs:+3:5: +5:6 + } + + bb7: { + StorageDead(_11); // scope 2 at $DIR/logical_and_in_conditional.rs:+5:5: +5:6 + StorageDead(_5); // scope 2 at $DIR/logical_and_in_conditional.rs:+5:5: +5:6 + StorageDead(_4); // scope 1 at $DIR/logical_and_in_conditional.rs:+6:1: +6:2 + StorageDead(_2); // scope 0 at $DIR/logical_and_in_conditional.rs:+6:1: +6:2 + return; // scope 0 at $DIR/logical_and_in_conditional.rs:+6:2: +6:2 + } + + bb8 (cleanup): { + resume; // scope 0 at $DIR/logical_and_in_conditional.rs:+0:1: +6:2 + } +} diff --git a/tests/mir-opt/building/logical_and_in_conditional.rs b/tests/mir-opt/building/logical_and_in_conditional.rs new file mode 100644 index 0000000000000..c4fa8c1f18221 --- /dev/null +++ b/tests/mir-opt/building/logical_and_in_conditional.rs @@ -0,0 +1,33 @@ +struct Droppy(bool); + +impl Drop for Droppy { + fn drop(&mut self) { + println!("drop"); + } +} + +// EMIT_MIR logical_and_in_conditional.test_and.built.after.mir +fn test_and(a: i32, b: i32, c: i32) { + if Droppy(a == 0).0 && Droppy(b == 0).0 && Droppy(c == 0).0 {} +} + +// https://github.com/rust-lang/rust/issues/111583 +// EMIT_MIR logical_and_in_conditional.function_from_issue_111583.built.after.mir +fn function_from_issue_111583(z: f64) { + let mask = (1 << 38) - 1; + let mut ret = 0; + if (z.to_bits() >> 8) & mask == 0 && z % 0.0625 < 1e-13 { + ret += 1; + } +} + +fn main() { + function_from_issue_111583(0.0); + for a in 0..1 { + for b in 0..1 { + for c in 0..1 { + test_and(a, b, c); + } + } + } +} diff --git a/tests/mir-opt/building/logical_and_in_conditional.test_and.built.after.mir b/tests/mir-opt/building/logical_and_in_conditional.test_and.built.after.mir new file mode 100644 index 0000000000000..8dcee8a6f7aea --- /dev/null +++ b/tests/mir-opt/building/logical_and_in_conditional.test_and.built.after.mir @@ -0,0 +1,110 @@ +// MIR for `test_and` after built + +fn test_and(_1: i32, _2: i32, _3: i32) -> () { + debug a => _1; // in scope 0 at $DIR/logical_and_in_conditional.rs:+0:13: +0:14 + debug b => _2; // in scope 0 at $DIR/logical_and_in_conditional.rs:+0:21: +0:22 + debug c => _3; // in scope 0 at $DIR/logical_and_in_conditional.rs:+0:29: +0:30 + let mut _0: (); // return place in scope 0 at $DIR/logical_and_in_conditional.rs:+0:37: +0:37 + let mut _4: bool; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:8: +1:24 + let mut _5: Droppy; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:8: +1:22 + let mut _6: bool; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:15: +1:21 + let mut _7: i32; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:15: +1:16 + let mut _8: bool; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:28: +1:44 + let mut _9: Droppy; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:28: +1:42 + let mut _10: bool; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:35: +1:41 + let mut _11: i32; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:35: +1:36 + let mut _12: bool; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:48: +1:64 + let mut _13: Droppy; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:48: +1:62 + let mut _14: bool; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:55: +1:61 + let mut _15: i32; // in scope 0 at $DIR/logical_and_in_conditional.rs:+1:55: +1:56 + + bb0: { + StorageLive(_4); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:8: +1:24 + StorageLive(_5); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:8: +1:22 + StorageLive(_6); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:15: +1:21 + StorageLive(_7); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:15: +1:16 + _7 = _1; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:15: +1:16 + _6 = Eq(move _7, const 0_i32); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:15: +1:21 + StorageDead(_7); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:20: +1:21 + _5 = Droppy(move _6); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:8: +1:22 + StorageDead(_6); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:21: +1:22 + _4 = (_5.0: bool); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:8: +1:24 + drop(_5) -> [return: bb1, unwind: bb12]; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:23: +1:24 + } + + bb1: { + StorageDead(_5); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:23: +1:24 + switchInt(move _4) -> [0: bb3, otherwise: bb2]; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:8: +1:24 + } + + bb2: { + StorageLive(_8); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:28: +1:44 + StorageLive(_9); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:28: +1:42 + StorageLive(_10); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:35: +1:41 + StorageLive(_11); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:35: +1:36 + _11 = _2; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:35: +1:36 + _10 = Eq(move _11, const 0_i32); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:35: +1:41 + StorageDead(_11); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:40: +1:41 + _9 = Droppy(move _10); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:28: +1:42 + StorageDead(_10); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:41: +1:42 + _8 = (_9.0: bool); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:28: +1:44 + drop(_9) -> [return: bb4, unwind: bb12]; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:43: +1:44 + } + + bb3: { + goto -> bb10; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:8: +1:24 + } + + bb4: { + StorageDead(_9); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:43: +1:44 + switchInt(move _8) -> [0: bb6, otherwise: bb5]; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:28: +1:44 + } + + bb5: { + StorageLive(_12); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:48: +1:64 + StorageLive(_13); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:48: +1:62 + StorageLive(_14); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:55: +1:61 + StorageLive(_15); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:55: +1:56 + _15 = _3; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:55: +1:56 + _14 = Eq(move _15, const 0_i32); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:55: +1:61 + StorageDead(_15); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:60: +1:61 + _13 = Droppy(move _14); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:48: +1:62 + StorageDead(_14); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:61: +1:62 + _12 = (_13.0: bool); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:48: +1:64 + drop(_13) -> [return: bb7, unwind: bb12]; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:63: +1:64 + } + + bb6: { + goto -> bb10; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:28: +1:44 + } + + bb7: { + StorageDead(_13); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:63: +1:64 + switchInt(move _12) -> [0: bb9, otherwise: bb8]; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:48: +1:64 + } + + bb8: { + _0 = const (); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:65: +1:67 + goto -> bb11; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:5: +1:67 + } + + bb9: { + goto -> bb10; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:48: +1:64 + } + + bb10: { + _0 = const (); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:67: +1:67 + goto -> bb11; // scope 0 at $DIR/logical_and_in_conditional.rs:+1:5: +1:67 + } + + bb11: { + StorageDead(_12); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:66: +1:67 + StorageDead(_8); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:66: +1:67 + StorageDead(_4); // scope 0 at $DIR/logical_and_in_conditional.rs:+1:66: +1:67 + return; // scope 0 at $DIR/logical_and_in_conditional.rs:+2:2: +2:2 + } + + bb12 (cleanup): { + resume; // scope 0 at $DIR/logical_and_in_conditional.rs:+0:1: +2:2 + } +} diff --git a/tests/ui/rfc-2497-if-let-chains/chains-without-let.rs b/tests/ui/rfc-2497-if-let-chains/chains-without-let.rs index e0dded1521760..d2401c6f87e35 100644 --- a/tests/ui/rfc-2497-if-let-chains/chains-without-let.rs +++ b/tests/ui/rfc-2497-if-let-chains/chains-without-let.rs @@ -1,7 +1,7 @@ fn and_chain() { let z; if true && { z = 3; true} && z == 3 {} - //~^ ERROR E0381 + // no longer ERROR E0381 } fn and_chain_2() { diff --git a/tests/ui/rfc-2497-if-let-chains/chains-without-let.stderr b/tests/ui/rfc-2497-if-let-chains/chains-without-let.stderr index 30d5a6779fcd7..38caf9cb0097c 100644 --- a/tests/ui/rfc-2497-if-let-chains/chains-without-let.stderr +++ b/tests/ui/rfc-2497-if-let-chains/chains-without-let.stderr @@ -1,13 +1,3 @@ -error[E0381]: used binding `z` is possibly-uninitialized - --> $DIR/chains-without-let.rs:3:34 - | -LL | let z; - | - binding declared here but left uninitialized -LL | if true && { z = 3; true} && z == 3 {} - | ----- ^ `z` used here but it is possibly-uninitialized - | | - | binding initialized here in some conditions - error[E0381]: used binding `z` is possibly-uninitialized --> $DIR/chains-without-let.rs:9:31 | @@ -28,6 +18,6 @@ LL | if false || { z = 3; false} || z == 3 {} | | | binding initialized here in some conditions -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0381`. diff --git a/tests/ui/suggestions/option-to-bool.stderr b/tests/ui/suggestions/option-to-bool.stderr index e042f07daeb1c..71cf51dfc5312 100644 --- a/tests/ui/suggestions/option-to-bool.stderr +++ b/tests/ui/suggestions/option-to-bool.stderr @@ -2,9 +2,7 @@ error[E0308]: mismatched types --> $DIR/option-to-bool.rs:4:16 | LL | if true && x {} - | ---- ^ expected `bool`, found `Option` - | | - | expected because this is `bool` + | ^ expected `bool`, found `Option` | = note: expected type `bool` found enum `Option`