From 79f12eb1ed02e763dafe13938996f69e6b0b5f7a Mon Sep 17 00:00:00 2001 From: dianne Date: Fri, 16 Jan 2026 15:42:25 -0800 Subject: [PATCH 1/2] remove some confusing mutation `oprnd_t` was used both for the type of the operand of a unary operator and for the type of the operator expression as a whole. Now it's only used for the operand's type. --- compiler/rustc_hir_typeck/src/expr.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 9f3ff0b2d03c2..1d7faf1345cfa 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -434,14 +434,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::UnOp::Not | hir::UnOp::Neg => expected, hir::UnOp::Deref => NoExpectation, }; - let mut oprnd_t = self.check_expr_with_expectation(oprnd, expected_inner); + let oprnd_t = self.check_expr_with_expectation(oprnd, expected_inner); - if !oprnd_t.references_error() { - oprnd_t = self.structurally_resolve_type(expr.span, oprnd_t); + if let Err(guar) = oprnd_t.error_reported() { + Ty::new_error(tcx, guar) + } else { + let oprnd_t = self.structurally_resolve_type(expr.span, oprnd_t); match unop { hir::UnOp::Deref => { if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) { - oprnd_t = ty; + ty } else { let mut err = self.dcx().create_err(CantDereference { span: expr.span, ty: oprnd_t }); @@ -451,26 +453,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } - oprnd_t = Ty::new_error(tcx, err.emit()); + Ty::new_error(tcx, err.emit()) } } hir::UnOp::Not => { let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); // If it's builtin, we can reuse the type, this helps inference. - if !(oprnd_t.is_integral() || *oprnd_t.kind() == ty::Bool) { - oprnd_t = result; + if oprnd_t.is_integral() || *oprnd_t.kind() == ty::Bool { + oprnd_t + } else { + result } } hir::UnOp::Neg => { let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); // If it's builtin, we can reuse the type, this helps inference. - if !oprnd_t.is_numeric() { - oprnd_t = result; - } + if oprnd_t.is_numeric() { oprnd_t } else { result } } } } - oprnd_t } fn check_expr_addr_of( From 91bbb692d5a32faae9a8fb3f212f518bd98ff3cd Mon Sep 17 00:00:00 2001 From: dianne Date: Fri, 16 Jan 2026 15:51:29 -0800 Subject: [PATCH 2/2] re-style `check_expr_unop` --- compiler/rustc_hir_typeck/src/expr.rs | 54 +++++++++++---------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 1d7faf1345cfa..885af3b909b8f 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -437,39 +437,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let oprnd_t = self.check_expr_with_expectation(oprnd, expected_inner); if let Err(guar) = oprnd_t.error_reported() { - Ty::new_error(tcx, guar) - } else { - let oprnd_t = self.structurally_resolve_type(expr.span, oprnd_t); - match unop { - hir::UnOp::Deref => { - if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) { - ty - } else { - let mut err = - self.dcx().create_err(CantDereference { span: expr.span, ty: oprnd_t }); - let sp = tcx.sess.source_map().start_point(expr.span).with_parent(None); - if let Some(sp) = - tcx.sess.psess.ambiguous_block_expr_parse.borrow().get(&sp) - { - err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); - } - Ty::new_error(tcx, err.emit()) - } - } - hir::UnOp::Not => { - let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); - // If it's builtin, we can reuse the type, this helps inference. - if oprnd_t.is_integral() || *oprnd_t.kind() == ty::Bool { - oprnd_t - } else { - result - } - } - hir::UnOp::Neg => { - let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); - // If it's builtin, we can reuse the type, this helps inference. - if oprnd_t.is_numeric() { oprnd_t } else { result } + return Ty::new_error(tcx, guar); + } + + let oprnd_t = self.structurally_resolve_type(expr.span, oprnd_t); + match unop { + hir::UnOp::Deref => self.lookup_derefing(expr, oprnd, oprnd_t).unwrap_or_else(|| { + let mut err = + self.dcx().create_err(CantDereference { span: expr.span, ty: oprnd_t }); + let sp = tcx.sess.source_map().start_point(expr.span).with_parent(None); + if let Some(sp) = tcx.sess.psess.ambiguous_block_expr_parse.borrow().get(&sp) { + err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } + Ty::new_error(tcx, err.emit()) + }), + hir::UnOp::Not => { + let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); + // If it's builtin, we can reuse the type, this helps inference. + if oprnd_t.is_integral() || *oprnd_t.kind() == ty::Bool { oprnd_t } else { result } + } + hir::UnOp::Neg => { + let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); + // If it's builtin, we can reuse the type, this helps inference. + if oprnd_t.is_numeric() { oprnd_t } else { result } } } }