Use ControlFlow in HIR visitors
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#![allow(rustc::diagnostic_outside_of_impl)]
|
||||
#![allow(rustc::untranslatable_diagnostic)]
|
||||
|
||||
use core::ops::ControlFlow;
|
||||
use hir::ExprKind;
|
||||
use rustc_errors::{Applicability, Diag};
|
||||
use rustc_hir as hir;
|
||||
@@ -727,30 +728,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
_ => local_decl.source_info.span,
|
||||
};
|
||||
|
||||
struct BindingFinder {
|
||||
span: Span,
|
||||
hir_id: Option<hir::HirId>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for BindingFinder {
|
||||
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
|
||||
if let hir::StmtKind::Local(local) = s.kind {
|
||||
if local.pat.span == self.span {
|
||||
self.hir_id = Some(local.hir_id);
|
||||
}
|
||||
}
|
||||
hir::intravisit::walk_stmt(self, s);
|
||||
}
|
||||
}
|
||||
|
||||
let def_id = self.body.source.def_id();
|
||||
let hir_id = if let Some(local_def_id) = def_id.as_local()
|
||||
&& let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
|
||||
{
|
||||
let body = self.infcx.tcx.hir().body(body_id);
|
||||
let mut v = BindingFinder { span: pat_span, hir_id: None };
|
||||
v.visit_body(body);
|
||||
v.hir_id
|
||||
BindingFinder { span: pat_span }.visit_body(body).break_value()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -859,17 +842,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let hir_map = self.infcx.tcx.hir();
|
||||
struct Finder<'tcx> {
|
||||
struct Finder {
|
||||
span: Span,
|
||||
expr: Option<&'tcx Expr<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for Finder<'tcx> {
|
||||
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
|
||||
if e.span == self.span && self.expr.is_none() {
|
||||
self.expr = Some(e);
|
||||
impl<'tcx> Visitor<'tcx> for Finder {
|
||||
type Result = ControlFlow<&'tcx Expr<'tcx>>;
|
||||
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) -> Self::Result {
|
||||
if e.span == self.span {
|
||||
ControlFlow::Break(e)
|
||||
} else {
|
||||
hir::intravisit::walk_expr(self, e)
|
||||
}
|
||||
hir::intravisit::walk_expr(self, e);
|
||||
}
|
||||
}
|
||||
if let Some(body_id) = hir_map.maybe_body_owned_by(self.mir_def_id())
|
||||
@@ -878,9 +862,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
// `span` corresponds to the expression being iterated, find the `for`-loop desugared
|
||||
// expression with that span in order to identify potential fixes when encountering a
|
||||
// read-only iterator that should be mutable.
|
||||
let mut v = Finder { span, expr: None };
|
||||
v.visit_block(block);
|
||||
if let Some(expr) = v.expr
|
||||
if let ControlFlow::Break(expr) = (Finder { span }).visit_block(block)
|
||||
&& let Call(_, [expr]) = expr.kind
|
||||
{
|
||||
match expr.kind {
|
||||
@@ -1179,29 +1161,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
Some((false, err_label_span, message)) => {
|
||||
struct BindingFinder {
|
||||
span: Span,
|
||||
hir_id: Option<hir::HirId>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for BindingFinder {
|
||||
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
|
||||
if let hir::StmtKind::Local(local) = s.kind {
|
||||
if local.pat.span == self.span {
|
||||
self.hir_id = Some(local.hir_id);
|
||||
}
|
||||
}
|
||||
hir::intravisit::walk_stmt(self, s);
|
||||
}
|
||||
}
|
||||
let def_id = self.body.source.def_id();
|
||||
let hir_id = if let Some(local_def_id) = def_id.as_local()
|
||||
&& let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
|
||||
{
|
||||
let body = self.infcx.tcx.hir().body(body_id);
|
||||
let mut v = BindingFinder { span: err_label_span, hir_id: None };
|
||||
v.visit_body(body);
|
||||
v.hir_id
|
||||
BindingFinder { span: err_label_span }.visit_body(body).break_value()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -1333,6 +1298,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
struct BindingFinder {
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for BindingFinder {
|
||||
type Result = ControlFlow<hir::HirId>;
|
||||
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) -> Self::Result {
|
||||
if let hir::StmtKind::Local(local) = s.kind
|
||||
&& local.pat.span == self.span
|
||||
{
|
||||
ControlFlow::Break(local.hir_id)
|
||||
} else {
|
||||
hir::intravisit::walk_stmt(self, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
|
||||
debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user