From 20431706a863f92cb37dc512fef6e48d192aaf2c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:38 +0200 Subject: Merging upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_ast_lowering/src/expr.rs | 87 ++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 33 deletions(-) (limited to 'compiler/rustc_ast_lowering/src/expr.rs') diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 7b8070d3c..ec9c39350 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -60,7 +60,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::Call(f, self.lower_exprs(args)) } } - ExprKind::MethodCall(ref seg, ref args, span) => { + ExprKind::MethodCall(ref seg, ref receiver, ref args, span) => { let hir_seg = self.arena.alloc(self.lower_path_segment( e.span, seg, @@ -68,9 +68,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ParenthesizedGenericArgs::Err, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), )); - let receiver = self.lower_expr(&args[0]); + let receiver = self.lower_expr(receiver); let args = - self.arena.alloc_from_iter(args[1..].iter().map(|x| self.lower_expr_mut(x))); + self.arena.alloc_from_iter(args.iter().map(|x| self.lower_expr_mut(x))); hir::ExprKind::MethodCall(hir_seg, receiver, args, self.lower_span(span)) } ExprKind::Binary(binop, ref lhs, ref rhs) => { @@ -359,7 +359,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let node_id = self.next_node_id(); // Add a definition for the in-band const def. - self.create_def(parent_def_id, node_id, DefPathData::AnonConst); + self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst); let anon_const = AnonConst { id: node_id, value: arg }; generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const))); @@ -387,32 +387,58 @@ impl<'hir> LoweringContext<'_, 'hir> { then: &Block, else_opt: Option<&Expr>, ) -> hir::ExprKind<'hir> { - let lowered_cond = self.lower_expr(cond); - let new_cond = self.manage_let_cond(lowered_cond); + let lowered_cond = self.lower_cond(cond); let then_expr = self.lower_block_expr(then); if let Some(rslt) = else_opt { - hir::ExprKind::If(new_cond, self.arena.alloc(then_expr), Some(self.lower_expr(rslt))) + hir::ExprKind::If( + lowered_cond, + self.arena.alloc(then_expr), + Some(self.lower_expr(rslt)), + ) } else { - hir::ExprKind::If(new_cond, self.arena.alloc(then_expr), None) + hir::ExprKind::If(lowered_cond, self.arena.alloc(then_expr), None) } } - // If `cond` kind is `let`, returns `let`. Otherwise, wraps and returns `cond` - // in a temporary block. - fn manage_let_cond(&mut self, cond: &'hir hir::Expr<'hir>) -> &'hir hir::Expr<'hir> { - fn has_let_expr<'hir>(expr: &'hir hir::Expr<'hir>) -> bool { - match expr.kind { - hir::ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs), - hir::ExprKind::Let(..) => true, + // 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, } } - if has_let_expr(cond) { - cond - } else { - let reason = DesugaringKind::CondTemporary; - let span_block = self.mark_span_with_reason(reason, cond.span, None); - self.expr_drop_temps(span_block, cond, AttrVec::new()) + + // 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. + // + // In order to mantain the drop behavior for the non `let` parts of the condition, + // 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) => + { + let op = self.lower_binop(*op); + let lhs = self.lower_cond(lhs); + let rhs = self.lower_cond(rhs); + + self.arena.alloc(self.expr( + cond.span, + hir::ExprKind::Binary(op, lhs, rhs), + AttrVec::new(), + )) + } + ExprKind::Let(..) => self.lower_expr(cond), + _ => { + let cond = self.lower_expr(cond); + let reason = DesugaringKind::CondTemporary; + let span_block = self.mark_span_with_reason(reason, cond.span, None); + self.expr_drop_temps(span_block, cond, AttrVec::new()) + } } } @@ -439,14 +465,13 @@ impl<'hir> LoweringContext<'_, 'hir> { body: &Block, opt_label: Option