diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs | 160 |
1 files changed, 79 insertions, 81 deletions
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs index 88ba112c8d5..3aaa269cd4b 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs @@ -424,87 +424,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { match label { Some((true, err_help_span, suggested_code)) => { - /// User cannot make signature of a trait mutable - /// without changing the trait. So we find if this - /// error belongs to a trait and if so we move - /// suggestion to the trait or disable it if it is - /// out of scope of this crate - let (is_trait_sig, local_trait) = { - if self.body.local_kind(local) != LocalKind::Arg { - (false, None) - } else { - let hir_map = self.infcx.tcx.hir(); - let my_hir = hir_map.local_def_id_to_hir_id( - self.body.source.def_id().as_local().unwrap(), - ); - match hir_map.find(hir_map.get_parent_node(my_hir)) { - Some(Node::Item(hir::Item { - kind: - hir::ItemKind::Impl(hir::Impl { - of_trait: - Some(hir::TraitRef { - path: - hir::Path { - res: - hir::def::Res::Def(_, td), - .. - }, - .. - }), - .. - }), - .. - })) => { - (true, td.as_local().and_then(|tld| { - let h = hir_map.local_def_id_to_hir_id(tld); - match hir_map.find(h) { - Some(Node::Item(hir::Item { - kind: hir::ItemKind::Trait( - _, _, _, _, - items - ), - .. - })) => { - let mut f_in_trait_opt = None; - for hir::TraitItemRef { id: fi, kind: k, .. } in *items { - let hi = fi.hir_id(); - if !matches!(k, hir::AssocItemKind::Fn { .. }) { - continue; - } - if hir_map.name(hi) != hir_map.name(my_hir) { - continue; - } - f_in_trait_opt = Some(hi); - break; - } - f_in_trait_opt.and_then(|f_in_trait| { - match hir_map.find(f_in_trait) { - Some(Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Fn(hir::FnSig { - decl: hir::FnDecl { - inputs, - .. - }, - .. - }, _), - .. - })) => { - let hir::Ty { span, .. } = inputs[local.index() - 1]; - Some(span) - }, - _ => None, - } - }) - //Some(hir_map.span(h)) - } - _ => None - } - })) - } - _ => (false, None), - } - } - }; + let (is_trait_sig, local_trait) = self.is_error_in_trait(local); if !is_trait_sig { err.span_suggestion( err_help_span, @@ -595,6 +515,84 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.buffer(&mut self.errors_buffer); } + + /// User cannot make signature of a trait mutable without changing the + /// trait. So we find if this error belongs to a trait and if so we move + /// suggestion to the trait or disable it if it is out of scope of this crate + fn is_error_in_trait(&self, local: Local) -> (bool, Option<Span>) { + if self.body.local_kind(local) != LocalKind::Arg { + return (false, None); + } + let hir_map = self.infcx.tcx.hir(); + let my_hir = hir_map.local_def_id_to_hir_id( + self.body.source.def_id().as_local().unwrap(), + ); + match hir_map.find(hir_map.get_parent_node(my_hir)) { + Some(Node::Item(hir::Item { + kind: + hir::ItemKind::Impl(hir::Impl { + of_trait: + Some(hir::TraitRef { + path: + hir::Path { + res: + hir::def::Res::Def(_, td), + .. + }, + .. + }), + .. + }), + .. + })) => { + (true, td.as_local().and_then(|tld| { + let h = hir_map.local_def_id_to_hir_id(tld); + match hir_map.find(h) { + Some(Node::Item(hir::Item { + kind: hir::ItemKind::Trait( + _, _, _, _, + items + ), + .. + })) => { + let mut f_in_trait_opt = None; + for hir::TraitItemRef { id: fi, kind: k, .. } in *items { + let hi = fi.hir_id(); + if !matches!(k, hir::AssocItemKind::Fn { .. }) { + continue; + } + if hir_map.name(hi) != hir_map.name(my_hir) { + continue; + } + f_in_trait_opt = Some(hi); + break; + } + f_in_trait_opt.and_then(|f_in_trait| { + match hir_map.find(f_in_trait) { + Some(Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(hir::FnSig { + decl: hir::FnDecl { + inputs, + .. + }, + .. + }, _), + .. + })) => { + let hir::Ty { span, .. } = inputs[local.index() - 1]; + Some(span) + }, + _ => None, + } + }) + } + _ => None + } + })) + } + _ => (false, None), + } + } // point to span of upvar making closure call require mutable borrow fn show_mutating_upvar( |
