diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 26bb6800348..bd068b29c12 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -540,19 +540,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } + /// Suggest `map[k] = v` => `map.insert(k, v)` and the like. fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'tcx>, span: Span) { let Some(adt) = ty.ty_adt_def() else { return }; let did = adt.did(); if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did) || self.infcx.tcx.is_diagnostic_item(sym::BTreeMap, did) { - struct V<'a, 'tcx> { + /// Walks through the HIR, looking for the corresponding span for this error. + /// When it finds it, see if it corresponds to assignment operator whose LHS + /// is an index expr. + struct SuggestIndexOperatorAlternativeVisitor<'a, 'tcx> { assign_span: Span, err: &'a mut Diag<'tcx>, ty: Ty<'tcx>, suggested: bool, } - impl<'a, 'tcx> Visitor<'tcx> for V<'a, 'tcx> { + impl<'a, 'tcx> Visitor<'tcx> for SuggestIndexOperatorAlternativeVisitor<'a, 'tcx> { fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) { hir::intravisit::walk_stmt(self, stmt); let expr = match stmt.kind { @@ -645,7 +649,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) else { return }; let body = self.infcx.tcx.hir().body(body_id); - let mut v = V { assign_span: span, err, ty, suggested: false }; + let mut v = SuggestIndexOperatorAlternativeVisitor { + assign_span: span, + err, + ty, + suggested: false, + }; v.visit_body(body); if !v.suggested { err.help(format!( diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index ee3436805ca..0b8ac9926e4 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -418,8 +418,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { { if let &hir::ClosureBinder::For { span: for_sp, .. } = binder { fn span_of_infer(ty: &hir::Ty<'_>) -> Option { - struct V; - impl<'v> Visitor<'v> for V { + /// Look for `_` anywhere in the signature of a `for<> ||` closure. + /// This is currently disallowed. + struct FindInferInClosureWithBinder; + impl<'v> Visitor<'v> for FindInferInClosureWithBinder { type Result = ControlFlow; fn visit_ty(&mut self, t: &'v hir::Ty<'v>) -> Self::Result { if matches!(t.kind, hir::TyKind::Infer) { @@ -429,7 +431,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } } } - V.visit_ty(ty).break_value() + FindInferInClosureWithBinder.visit_ty(ty).break_value() } let infer_in_rt_sp = match fn_decl.output { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 8ea1a88be5d..5f5ff40fb9f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1916,22 +1916,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat: &'tcx hir::Pat<'tcx>, ty: Ty<'tcx>, ) { - struct V { - pat_hir_ids: Vec, - } - - impl<'tcx> Visitor<'tcx> for V { - fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) { - self.pat_hir_ids.push(p.hir_id); - hir::intravisit::walk_pat(self, p); - } - } if let Err(guar) = ty.error_reported() { + struct OverwritePatternsWithError { + pat_hir_ids: Vec, + } + impl<'tcx> Visitor<'tcx> for OverwritePatternsWithError { + fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) { + self.pat_hir_ids.push(p.hir_id); + hir::intravisit::walk_pat(self, p); + } + } // Override the types everywhere with `err()` to avoid knock on errors. let err = Ty::new_error(self.tcx, guar); self.write_ty(hir_id, err); self.write_ty(pat.hir_id, err); - let mut visitor = V { pat_hir_ids: vec![] }; + let mut visitor = OverwritePatternsWithError { pat_hir_ids: vec![] }; hir::intravisit::walk_pat(&mut visitor, pat); // Mark all the subpatterns as `{type error}` as well. This allows errors for specific // subpatterns to be silenced. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 7a62030353d..aef98dbad5f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1128,10 +1128,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err: &mut Diag<'_>, ) -> bool { let span = obligation.cause.span; - struct V { + /// Look for the (direct) sub-expr of `?`, and return it if it's a `.` method call. + struct FindMethodSubexprOfTry { search_span: Span, } - impl<'v> Visitor<'v> for V { + impl<'v> Visitor<'v> for FindMethodSubexprOfTry { type Result = ControlFlow<&'v hir::Expr<'v>>; fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) -> Self::Result { if let hir::ExprKind::Match(expr, _arms, hir::MatchSource::TryDesugar(_)) = ex.kind @@ -1149,8 +1150,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. }) => body_id, _ => return false, }; - let ControlFlow::Break(expr) = - (V { search_span: span }).visit_body(self.tcx.hir().body(*body_id)) + let ControlFlow::Break(expr) = (FindMethodSubexprOfTry { search_span: span }) + .visit_body(self.tcx.hir().body(*body_id)) else { return false; };