|
3 | 3 | use std::borrow::Cow; |
4 | 4 |
|
5 | 5 | use rustc_abi::ExternAbi; |
6 | | -use rustc_ast::Label; |
| 6 | +use rustc_ast::{AssignOpKind, Label}; |
7 | 7 | use rustc_errors::codes::*; |
8 | 8 | use rustc_errors::{ |
9 | 9 | Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic, |
10 | | - EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, |
| 10 | + EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, struct_span_code_err, |
11 | 11 | }; |
12 | 12 | use rustc_hir as hir; |
13 | 13 | use rustc_hir::ExprKind; |
14 | 14 | use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; |
15 | 15 | use rustc_middle::ty::{self, Ty}; |
16 | 16 | use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; |
| 17 | +use rustc_span::source_map::Spanned; |
17 | 18 | use rustc_span::{Ident, Span, Symbol}; |
18 | 19 |
|
19 | | -use crate::fluent_generated as fluent; |
| 20 | +use crate::{FnCtxt, fluent_generated as fluent}; |
20 | 21 |
|
21 | 22 | #[derive(Diagnostic)] |
22 | 23 | #[diag(hir_typeck_base_expression_double_dot, code = E0797)] |
@@ -1133,6 +1134,39 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for NakedFunctionsAsmBlock { |
1133 | 1134 | } |
1134 | 1135 | } |
1135 | 1136 |
|
| 1137 | +pub(crate) fn maybe_emit_plus_equals_diagnostic<'a>( |
| 1138 | + fnctxt: &FnCtxt<'a, '_>, |
| 1139 | + assign_op: Spanned<AssignOpKind>, |
| 1140 | + lhs_expr: &hir::Expr<'_>, |
| 1141 | +) -> Result<(), Diag<'a>> { |
| 1142 | + if assign_op.node == hir::AssignOpKind::AddAssign |
| 1143 | + && let hir::ExprKind::Binary(bin_op, left, right) = &lhs_expr.kind |
| 1144 | + && bin_op.node == hir::BinOpKind::And |
| 1145 | + && crate::op::contains_let_in_chain(left) |
| 1146 | + && let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &right.kind |
| 1147 | + && matches!(path.res, hir::def::Res::Local(_)) |
| 1148 | + { |
| 1149 | + let mut err = struct_span_code_err!( |
| 1150 | + fnctxt.dcx(), |
| 1151 | + assign_op.span, |
| 1152 | + E0368, |
| 1153 | + "binary assignment operation `+=` cannot be used in a let chain", |
| 1154 | + ); |
| 1155 | + |
| 1156 | + err.span_label(assign_op.span, "cannot use `+=` in a let chain"); |
| 1157 | + |
| 1158 | + err.span_suggestion( |
| 1159 | + assign_op.span, |
| 1160 | + "you might have meant to compare with `==` instead of assigning with `+=`", |
| 1161 | + "==", |
| 1162 | + Applicability::MaybeIncorrect, |
| 1163 | + ); |
| 1164 | + |
| 1165 | + return Err(err); |
| 1166 | + } |
| 1167 | + Ok(()) |
| 1168 | +} |
| 1169 | + |
1136 | 1170 | #[derive(Diagnostic)] |
1137 | 1171 | #[diag(hir_typeck_naked_functions_must_naked_asm, code = E0787)] |
1138 | 1172 | pub(crate) struct NakedFunctionsMustNakedAsm { |
|
0 commit comments