Format all the let chains in compiler
This commit is contained in:
parent
2763ca50da
commit
b2d2184ede
206 changed files with 3120 additions and 2228 deletions
|
@ -351,7 +351,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
// Check if we are in a situation of `ident @ ident` where we want to suggest
|
||||
// `ref ident @ ref ident` or `ref ident @ Struct { ref ident }`.
|
||||
if let Some(subpat) = sub && self.pat.is_none() {
|
||||
if let Some(subpat) = sub
|
||||
&& self.pat.is_none()
|
||||
{
|
||||
self.visit_pat(subpat);
|
||||
if self.pat.is_some() {
|
||||
self.parent_pat = Some(p);
|
||||
|
@ -370,7 +372,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let mut finder =
|
||||
ExpressionFinder { expr_span: move_span, expr: None, pat: None, parent_pat: None };
|
||||
finder.visit_expr(expr);
|
||||
if let Some(span) = span && let Some(expr) = finder.expr {
|
||||
if let Some(span) = span
|
||||
&& let Some(expr) = finder.expr
|
||||
{
|
||||
for (_, expr) in hir.parent_iter(expr.hir_id) {
|
||||
if let hir::Node::Expr(expr) = expr {
|
||||
if expr.span.contains(span) {
|
||||
|
@ -425,10 +429,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
Some(hir::intravisit::FnKind::Method(..)) => "method",
|
||||
Some(hir::intravisit::FnKind::Closure) => "closure",
|
||||
};
|
||||
span.push_span_label(
|
||||
ident.span,
|
||||
format!("in this {descr}"),
|
||||
);
|
||||
span.push_span_label(ident.span, format!("in this {descr}"));
|
||||
err.span_note(
|
||||
span,
|
||||
format!(
|
||||
|
@ -441,15 +442,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let ty = place.ty(self.body, self.infcx.tcx).ty;
|
||||
if let hir::Node::Expr(parent_expr) = parent
|
||||
&& let hir::ExprKind::Call(call_expr, _) = parent_expr.kind
|
||||
&& let hir::ExprKind::Path(
|
||||
hir::QPath::LangItem(LangItem::IntoIterIntoIter, _, _)
|
||||
) = call_expr.kind
|
||||
&& let hir::ExprKind::Path(hir::QPath::LangItem(
|
||||
LangItem::IntoIterIntoIter,
|
||||
_,
|
||||
_,
|
||||
)) = call_expr.kind
|
||||
{
|
||||
// Do not suggest `.clone()` in a `for` loop, we already suggest borrowing.
|
||||
} else if let UseSpans::FnSelfUse {
|
||||
kind: CallKind::Normal { .. },
|
||||
..
|
||||
} = move_spans {
|
||||
} else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } =
|
||||
move_spans
|
||||
{
|
||||
// We already suggest cloning for these cases in `explain_captures`.
|
||||
} else {
|
||||
self.suggest_cloning(err, ty, expr, move_span);
|
||||
|
@ -602,10 +604,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
if self.sugg_span.is_some() {
|
||||
return;
|
||||
}
|
||||
if let hir::StmtKind::Local(hir::Local {
|
||||
span, ty, init: None, ..
|
||||
}) = &ex.kind && span.contains(self.decl_span) {
|
||||
self.sugg_span = ty.map_or(Some(self.decl_span), |ty| Some(ty.span));
|
||||
if let hir::StmtKind::Local(hir::Local { span, ty, init: None, .. }) = &ex.kind
|
||||
&& span.contains(self.decl_span)
|
||||
{
|
||||
self.sugg_span = ty.map_or(Some(self.decl_span), |ty| Some(ty.span));
|
||||
}
|
||||
hir::intravisit::walk_stmt(self, ex);
|
||||
}
|
||||
|
@ -743,19 +745,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
".clone()".to_owned()
|
||||
};
|
||||
if let Some(clone_trait_def) = tcx.lang_items().clone_trait()
|
||||
&& self.infcx
|
||||
.type_implements_trait(
|
||||
clone_trait_def,
|
||||
[ty],
|
||||
self.param_env,
|
||||
)
|
||||
&& self
|
||||
.infcx
|
||||
.type_implements_trait(clone_trait_def, [ty], self.param_env)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
let msg = if let ty::Adt(def, _) = ty.kind()
|
||||
&& [
|
||||
tcx.get_diagnostic_item(sym::Arc),
|
||||
tcx.get_diagnostic_item(sym::Rc),
|
||||
].contains(&Some(def.did()))
|
||||
&& [tcx.get_diagnostic_item(sym::Arc), tcx.get_diagnostic_item(sym::Rc)]
|
||||
.contains(&Some(def.did()))
|
||||
{
|
||||
"clone the value to increment its reference count"
|
||||
} else {
|
||||
|
@ -1350,9 +1347,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
// };
|
||||
// corresponding to the desugaring of a for loop `for <pat> in <head> { <body> }`.
|
||||
if let hir::ExprKind::Call(path, [arg]) = ex.kind
|
||||
&& let hir::ExprKind::Path(
|
||||
hir::QPath::LangItem(LangItem::IntoIterIntoIter, _, _),
|
||||
) = path.kind
|
||||
&& let hir::ExprKind::Path(hir::QPath::LangItem(
|
||||
LangItem::IntoIterIntoIter,
|
||||
_,
|
||||
_,
|
||||
)) = path.kind
|
||||
&& arg.span.contains(self.issue_span)
|
||||
{
|
||||
// Find `IntoIterator::into_iter(<head>)`
|
||||
|
@ -1370,18 +1369,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
..
|
||||
}) = stmt.kind
|
||||
&& let hir::ExprKind::Call(path, _args) = call.kind
|
||||
&& let hir::ExprKind::Path(
|
||||
hir::QPath::LangItem(LangItem::IteratorNext, _, _),
|
||||
) = path.kind
|
||||
&& let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IteratorNext, _, _)) =
|
||||
path.kind
|
||||
&& let hir::PatKind::Struct(path, [field, ..], _) = bind.pat.kind
|
||||
&& let hir::QPath::LangItem(LangItem::OptionSome, pat_span, _) = path
|
||||
&& call.span.contains(self.issue_span)
|
||||
{
|
||||
// Find `<pat>` and the span for the whole `for` loop.
|
||||
if let PatField { pat: hir::Pat {
|
||||
kind: hir::PatKind::Binding(_, _, ident, ..),
|
||||
if let PatField {
|
||||
pat: hir::Pat { kind: hir::PatKind::Binding(_, _, ident, ..), .. },
|
||||
..
|
||||
}, ..} = field {
|
||||
} = field
|
||||
{
|
||||
self.loop_bind = Some(ident);
|
||||
}
|
||||
self.head_span = Some(*head_span);
|
||||
|
@ -1441,18 +1440,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
// A bare path doesn't need a `let` assignment, it's already a simple
|
||||
// binding access.
|
||||
// As a new binding wasn't added, we don't need to modify the advancing call.
|
||||
sugg.push((
|
||||
loop_span.with_hi(pat_span.lo()),
|
||||
format!("while let Some("),
|
||||
));
|
||||
sugg.push((loop_span.with_hi(pat_span.lo()), format!("while let Some(")));
|
||||
sugg.push((
|
||||
pat_span.shrink_to_hi().with_hi(head.span.lo()),
|
||||
") = ".to_string(),
|
||||
));
|
||||
sugg.push((
|
||||
head.span.shrink_to_hi(),
|
||||
".next()".to_string(),
|
||||
));
|
||||
sugg.push((head.span.shrink_to_hi(), ".next()".to_string()));
|
||||
} else {
|
||||
// Needs a new a `let` binding.
|
||||
let indent = if let Some(indent) = sm.indentation_before(loop_span) {
|
||||
|
@ -1483,11 +1476,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
sugg.push((recv.span, "iter".to_string()));
|
||||
}
|
||||
}
|
||||
err.multipart_suggestion(
|
||||
msg,
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
|
||||
} else {
|
||||
err.help(msg);
|
||||
}
|
||||
|
@ -1666,69 +1655,80 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
|
||||
if e.span.contains(self.capture_span) {
|
||||
if let hir::ExprKind::Closure(&hir::Closure {
|
||||
movability: None,
|
||||
body,
|
||||
fn_arg_span,
|
||||
fn_decl: hir::FnDecl{ inputs, .. },
|
||||
..
|
||||
}) = e.kind &&
|
||||
let Some(hir::Node::Expr(body )) = self.hir.find(body.hir_id) {
|
||||
self.suggest_arg = "this: &Self".to_string();
|
||||
if inputs.len() > 0 {
|
||||
self.suggest_arg.push_str(", ");
|
||||
}
|
||||
self.in_closure = true;
|
||||
self.closure_arg_span = fn_arg_span;
|
||||
self.visit_expr(body);
|
||||
self.in_closure = false;
|
||||
movability: None,
|
||||
body,
|
||||
fn_arg_span,
|
||||
fn_decl: hir::FnDecl { inputs, .. },
|
||||
..
|
||||
}) = e.kind
|
||||
&& let Some(hir::Node::Expr(body)) = self.hir.find(body.hir_id)
|
||||
{
|
||||
self.suggest_arg = "this: &Self".to_string();
|
||||
if inputs.len() > 0 {
|
||||
self.suggest_arg.push_str(", ");
|
||||
}
|
||||
self.in_closure = true;
|
||||
self.closure_arg_span = fn_arg_span;
|
||||
self.visit_expr(body);
|
||||
self.in_closure = false;
|
||||
}
|
||||
}
|
||||
if let hir::Expr { kind: hir::ExprKind::Path(path), .. } = e {
|
||||
if let hir::QPath::Resolved(_, hir::Path { segments: [seg], ..}) = path &&
|
||||
seg.ident.name == kw::SelfLower && self.in_closure {
|
||||
self.closure_change_spans.push(e.span);
|
||||
if let hir::QPath::Resolved(_, hir::Path { segments: [seg], .. }) = path
|
||||
&& seg.ident.name == kw::SelfLower
|
||||
&& self.in_closure
|
||||
{
|
||||
self.closure_change_spans.push(e.span);
|
||||
}
|
||||
}
|
||||
hir::intravisit::walk_expr(self, e);
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, local: &'hir hir::Local<'hir>) {
|
||||
if let hir::Pat { kind: hir::PatKind::Binding(_, hir_id, _ident, _), .. } = local.pat &&
|
||||
let Some(init) = local.init
|
||||
if let hir::Pat { kind: hir::PatKind::Binding(_, hir_id, _ident, _), .. } =
|
||||
local.pat
|
||||
&& let Some(init) = local.init
|
||||
{
|
||||
if let hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure {
|
||||
movability: None,
|
||||
..
|
||||
}), .. } = init &&
|
||||
init.span.contains(self.capture_span) {
|
||||
self.closure_local_id = Some(*hir_id);
|
||||
if let hir::Expr {
|
||||
kind: hir::ExprKind::Closure(&hir::Closure { movability: None, .. }),
|
||||
..
|
||||
} = init
|
||||
&& init.span.contains(self.capture_span)
|
||||
{
|
||||
self.closure_local_id = Some(*hir_id);
|
||||
}
|
||||
}
|
||||
hir::intravisit::walk_local(self, local);
|
||||
}
|
||||
|
||||
fn visit_stmt(&mut self, s: &'hir hir::Stmt<'hir>) {
|
||||
if let hir::StmtKind::Semi(e) = s.kind &&
|
||||
let hir::ExprKind::Call(hir::Expr { kind: hir::ExprKind::Path(path), ..}, args) = e.kind &&
|
||||
let hir::QPath::Resolved(_, hir::Path { segments: [seg], ..}) = path &&
|
||||
let Res::Local(hir_id) = seg.res &&
|
||||
Some(hir_id) == self.closure_local_id {
|
||||
let (span, arg_str) = if args.len() > 0 {
|
||||
(args[0].span.shrink_to_lo(), "self, ".to_string())
|
||||
} else {
|
||||
let span = e.span.trim_start(seg.ident.span).unwrap_or(e.span);
|
||||
(span, "(self)".to_string())
|
||||
};
|
||||
self.closure_call_changes.push((span, arg_str));
|
||||
if let hir::StmtKind::Semi(e) = s.kind
|
||||
&& let hir::ExprKind::Call(
|
||||
hir::Expr { kind: hir::ExprKind::Path(path), .. },
|
||||
args,
|
||||
) = e.kind
|
||||
&& let hir::QPath::Resolved(_, hir::Path { segments: [seg], .. }) = path
|
||||
&& let Res::Local(hir_id) = seg.res
|
||||
&& Some(hir_id) == self.closure_local_id
|
||||
{
|
||||
let (span, arg_str) = if args.len() > 0 {
|
||||
(args[0].span.shrink_to_lo(), "self, ".to_string())
|
||||
} else {
|
||||
let span = e.span.trim_start(seg.ident.span).unwrap_or(e.span);
|
||||
(span, "(self)".to_string())
|
||||
};
|
||||
self.closure_call_changes.push((span, arg_str));
|
||||
}
|
||||
hir::intravisit::walk_stmt(self, s);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(hir::Node::ImplItem(
|
||||
hir::ImplItem { kind: hir::ImplItemKind::Fn(_fn_sig, body_id), .. }
|
||||
)) = hir.find(self.mir_hir_id()) &&
|
||||
let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id) {
|
||||
if let Some(hir::Node::ImplItem(hir::ImplItem {
|
||||
kind: hir::ImplItemKind::Fn(_fn_sig, body_id),
|
||||
..
|
||||
})) = hir.find(self.mir_hir_id())
|
||||
&& let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id)
|
||||
{
|
||||
let mut finder = ExpressionFinder {
|
||||
capture_span: *capture_kind_span,
|
||||
closure_change_spans: vec![],
|
||||
|
@ -2299,15 +2299,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
visitor.visit_stmt(stmt);
|
||||
|
||||
let typeck_results = self.infcx.tcx.typeck(self.mir_def_id());
|
||||
let expr_ty: Option<Ty<'_>> = visitor.prop_expr.map(|expr| typeck_results.expr_ty(expr).peel_refs());
|
||||
let expr_ty: Option<Ty<'_>> =
|
||||
visitor.prop_expr.map(|expr| typeck_results.expr_ty(expr).peel_refs());
|
||||
|
||||
let is_format_arguments_item =
|
||||
if let Some(expr_ty) = expr_ty
|
||||
&& let ty::Adt(adt, _) = expr_ty.kind() {
|
||||
self.infcx.tcx.lang_items().get(LangItem::FormatArguments) == Some(adt.did())
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let is_format_arguments_item = if let Some(expr_ty) = expr_ty
|
||||
&& let ty::Adt(adt, _) = expr_ty.kind()
|
||||
{
|
||||
self.infcx.tcx.lang_items().get(LangItem::FormatArguments)
|
||||
== Some(adt.did())
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if visitor.found == 0
|
||||
&& stmt.span.contains(proper_span)
|
||||
|
|
|
@ -76,10 +76,10 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
expr_finder.visit_expr(body.value);
|
||||
if let Some(mut expr) = expr_finder.result {
|
||||
while let hir::ExprKind::AddrOf(_, _, inner)
|
||||
| hir::ExprKind::Unary(hir::UnOp::Deref, inner)
|
||||
| hir::ExprKind::Field(inner, _)
|
||||
| hir::ExprKind::MethodCall(_, inner, _, _)
|
||||
| hir::ExprKind::Index(inner, _, _) = &expr.kind
|
||||
| hir::ExprKind::Unary(hir::UnOp::Deref, inner)
|
||||
| hir::ExprKind::Field(inner, _)
|
||||
| hir::ExprKind::MethodCall(_, inner, _, _)
|
||||
| hir::ExprKind::Index(inner, _, _) = &expr.kind
|
||||
{
|
||||
expr = inner;
|
||||
}
|
||||
|
@ -88,10 +88,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
&& let hir::def::Res::Local(hir_id) = p.res
|
||||
&& let Some(hir::Node::Pat(pat)) = tcx.hir().find(hir_id)
|
||||
{
|
||||
err.span_label(
|
||||
pat.span,
|
||||
format!("binding `{ident}` declared here"),
|
||||
);
|
||||
err.span_label(pat.span, format!("binding `{ident}` declared here"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +416,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
if self.local_names[local].is_some()
|
||||
&& let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place
|
||||
&& let Some(borrowed_local) = place.as_local()
|
||||
&& self.local_names[borrowed_local].is_some() && local != borrowed_local
|
||||
&& self.local_names[borrowed_local].is_some()
|
||||
&& local != borrowed_local
|
||||
{
|
||||
should_note_order = true;
|
||||
}
|
||||
|
|
|
@ -780,19 +780,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
|
||||
debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
|
||||
if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind
|
||||
&& let AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) = **kind
|
||||
&& let AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) =
|
||||
**kind
|
||||
{
|
||||
debug!("move_spans: def_id={:?} places={:?}", def_id, places);
|
||||
let def_id = def_id.expect_local();
|
||||
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
||||
self.closure_span(def_id, moved_place, places)
|
||||
{
|
||||
return ClosureUse {
|
||||
generator_kind,
|
||||
args_span,
|
||||
capture_kind_span,
|
||||
path_span,
|
||||
};
|
||||
return ClosureUse { generator_kind, args_span, capture_kind_span, path_span };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1123,7 +1119,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
&self.infcx.tcx.sess.parse_sess.span_diagnostic,
|
||||
CaptureReasonSuggest::FreshReborrow {
|
||||
span: move_span.shrink_to_hi(),
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
if let Some(clone_trait) = tcx.lang_items().clone_trait()
|
||||
&& let trait_ref = ty::TraitRef::new(tcx, clone_trait, [ty])
|
||||
|
|
|
@ -396,17 +396,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
let upvar_hir_id = captured_place.get_root_variable();
|
||||
|
||||
if let Some(Node::Pat(pat)) = self.infcx.tcx.hir().find(upvar_hir_id)
|
||||
&& let hir::PatKind::Binding(
|
||||
hir::BindingAnnotation::NONE,
|
||||
_,
|
||||
upvar_ident,
|
||||
_,
|
||||
) = pat.kind
|
||||
&& let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, upvar_ident, _) =
|
||||
pat.kind
|
||||
{
|
||||
if upvar_ident.name == kw::SelfLower {
|
||||
for (_, node) in self.infcx.tcx.hir().parent_iter(upvar_hir_id) {
|
||||
if let Some(fn_decl) = node.fn_decl() {
|
||||
if !matches!(fn_decl.implicit_self, hir::ImplicitSelfKind::ImmRef | hir::ImplicitSelfKind::MutRef) {
|
||||
if !matches!(
|
||||
fn_decl.implicit_self,
|
||||
hir::ImplicitSelfKind::ImmRef | hir::ImplicitSelfKind::MutRef
|
||||
) {
|
||||
err.span_suggestion(
|
||||
upvar_ident.span,
|
||||
"consider changing this to be mutable",
|
||||
|
@ -573,7 +572,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
self.ty,
|
||||
),
|
||||
vec![
|
||||
vec![ // val.insert(index, rv);
|
||||
vec![
|
||||
// val.insert(index, rv);
|
||||
(
|
||||
val.span.shrink_to_hi().with_hi(index.span.lo()),
|
||||
".insert(".to_string(),
|
||||
|
@ -584,7 +584,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
),
|
||||
(rv.span.shrink_to_hi(), ")".to_string()),
|
||||
],
|
||||
vec![ // val.get_mut(index).map(|v| { *v = rv; });
|
||||
vec![
|
||||
// val.get_mut(index).map(|v| { *v = rv; });
|
||||
(
|
||||
val.span.shrink_to_hi().with_hi(index.span.lo()),
|
||||
".get_mut(".to_string(),
|
||||
|
@ -593,12 +594,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
index.span.shrink_to_hi().with_hi(place.span.hi()),
|
||||
").map(|val| { *val".to_string(),
|
||||
),
|
||||
(
|
||||
rv.span.shrink_to_hi(),
|
||||
"; })".to_string(),
|
||||
),
|
||||
(rv.span.shrink_to_hi(), "; })".to_string()),
|
||||
],
|
||||
vec![ // let x = val.entry(index).or_insert(rv);
|
||||
vec![
|
||||
// let x = val.entry(index).or_insert(rv);
|
||||
(val.span.shrink_to_lo(), "let val = ".to_string()),
|
||||
(
|
||||
val.span.shrink_to_hi().with_hi(index.span.lo()),
|
||||
|
@ -747,10 +746,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
&& let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id)
|
||||
{
|
||||
let body = hir_map.body(body_id);
|
||||
let mut v = BindingFinder {
|
||||
span: pat_span,
|
||||
hir_id: None,
|
||||
};
|
||||
let mut v = BindingFinder { span: pat_span, hir_id: None };
|
||||
v.visit_body(body);
|
||||
v.hir_id
|
||||
} else {
|
||||
|
@ -766,7 +762,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
|
||||
..
|
||||
})) = hir_map.find(hir_id)
|
||||
&& let Ok(name) = self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span)
|
||||
&& let Ok(name) =
|
||||
self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span)
|
||||
{
|
||||
err.span_suggestion(
|
||||
pat_span,
|
||||
|
@ -879,12 +876,11 @@ 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,
|
||||
};
|
||||
let mut v = Finder { span, expr: None };
|
||||
v.visit_block(block);
|
||||
if let Some(expr) = v.expr && let Call(_, [expr]) = expr.kind {
|
||||
if let Some(expr) = v.expr
|
||||
&& let Call(_, [expr]) = expr.kind
|
||||
{
|
||||
match expr.kind {
|
||||
MethodCall(path_segment, _, _, span) => {
|
||||
// We have `for _ in iter.read_only_iter()`, try to
|
||||
|
@ -1032,38 +1028,42 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
let source = self.body.source;
|
||||
let hir = self.infcx.tcx.hir();
|
||||
if let InstanceDef::Item(def_id) = source.instance
|
||||
&& let Some(Node::Expr(hir::Expr { hir_id, kind, ..})) = hir.get_if_local(def_id)
|
||||
&& let ExprKind::Closure(closure) = kind && closure.movability == None
|
||||
&& let Some(Node::Expr(expr)) = hir.find_parent(*hir_id) {
|
||||
let mut cur_expr = expr;
|
||||
while let ExprKind::MethodCall(path_segment, recv, _, _) = cur_expr.kind {
|
||||
if path_segment.ident.name == sym::iter {
|
||||
// check `_ty` has `iter_mut` method
|
||||
let res = self
|
||||
.infcx
|
||||
.tcx
|
||||
.typeck(path_segment.hir_id.owner.def_id)
|
||||
.type_dependent_def_id(cur_expr.hir_id)
|
||||
.and_then(|def_id| self.infcx.tcx.impl_of_method(def_id))
|
||||
.map(|def_id| self.infcx.tcx.associated_items(def_id))
|
||||
.map(|assoc_items| {
|
||||
assoc_items.filter_by_name_unhygienic(sym::iter_mut).peekable()
|
||||
});
|
||||
&& let Some(Node::Expr(hir::Expr { hir_id, kind, .. })) = hir.get_if_local(def_id)
|
||||
&& let ExprKind::Closure(closure) = kind
|
||||
&& closure.movability == None
|
||||
&& let Some(Node::Expr(expr)) = hir.find_parent(*hir_id)
|
||||
{
|
||||
let mut cur_expr = expr;
|
||||
while let ExprKind::MethodCall(path_segment, recv, _, _) = cur_expr.kind {
|
||||
if path_segment.ident.name == sym::iter {
|
||||
// check `_ty` has `iter_mut` method
|
||||
let res = self
|
||||
.infcx
|
||||
.tcx
|
||||
.typeck(path_segment.hir_id.owner.def_id)
|
||||
.type_dependent_def_id(cur_expr.hir_id)
|
||||
.and_then(|def_id| self.infcx.tcx.impl_of_method(def_id))
|
||||
.map(|def_id| self.infcx.tcx.associated_items(def_id))
|
||||
.map(|assoc_items| {
|
||||
assoc_items.filter_by_name_unhygienic(sym::iter_mut).peekable()
|
||||
});
|
||||
|
||||
if let Some(mut res) = res && res.peek().is_some() {
|
||||
err.span_suggestion_verbose(
|
||||
path_segment.ident.span,
|
||||
"you may want to use `iter_mut` here",
|
||||
"iter_mut",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
cur_expr = recv;
|
||||
if let Some(mut res) = res
|
||||
&& res.peek().is_some()
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
path_segment.ident.span,
|
||||
"you may want to use `iter_mut` here",
|
||||
"iter_mut",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
cur_expr = recv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_make_local_mut(
|
||||
|
@ -1200,14 +1200,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
}
|
||||
let hir_map = self.infcx.tcx.hir();
|
||||
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) = hir_map.maybe_body_owned_by(local_def_id)
|
||||
let hir_id = if let Some(local_def_id) = def_id.as_local()
|
||||
&& let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id)
|
||||
{
|
||||
let body = hir_map.body(body_id);
|
||||
let mut v = BindingFinder {
|
||||
span: err_label_span,
|
||||
hir_id: None,
|
||||
};
|
||||
let mut v = BindingFinder { span: err_label_span, hir_id: None };
|
||||
v.visit_body(body);
|
||||
v.hir_id
|
||||
} else {
|
||||
|
@ -1215,15 +1212,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
};
|
||||
|
||||
if let Some(hir_id) = hir_id
|
||||
&& let Some(hir::Node::Local(local)) = hir_map.find(hir_id)
|
||||
&& let Some(hir::Node::Local(local)) = hir_map.find(hir_id)
|
||||
{
|
||||
let (changing, span, sugg) = match local.ty {
|
||||
Some(ty) => ("changing", ty.span, message),
|
||||
None => (
|
||||
"specifying",
|
||||
local.pat.span.shrink_to_hi(),
|
||||
format!(": {message}"),
|
||||
),
|
||||
None => {
|
||||
("specifying", local.pat.span.shrink_to_hi(), format!(": {message}"))
|
||||
}
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
|
@ -1234,9 +1229,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
} else {
|
||||
err.span_label(
|
||||
err_label_span,
|
||||
format!(
|
||||
"consider changing this binding's type to be: `{message}`"
|
||||
),
|
||||
format!("consider changing this binding's type to be: `{message}`"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1380,11 +1373,7 @@ fn suggest_ampmut<'tcx>(
|
|||
let ty_mut = decl_ty.builtin_deref(true).unwrap();
|
||||
assert_eq!(ty_mut.mutbl, hir::Mutability::Not);
|
||||
|
||||
(
|
||||
false,
|
||||
span,
|
||||
format!("{}mut {}", if decl_ty.is_ref() {"&"} else {"*"}, ty_mut.ty)
|
||||
)
|
||||
(false, span, format!("{}mut {}", if decl_ty.is_ref() { "&" } else { "*" }, ty_mut.ty))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -942,9 +942,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
ty::ClauseKind::Projection(data) if data.projection_ty.self_ty() == ty => {}
|
||||
_ => return false,
|
||||
}
|
||||
tcx.any_free_region_meets(pred, |r| {
|
||||
*r == ty::ReEarlyBound(region)
|
||||
})
|
||||
tcx.any_free_region_meets(pred, |r| *r == ty::ReEarlyBound(region))
|
||||
})
|
||||
} else {
|
||||
false
|
||||
|
|
|
@ -173,7 +173,9 @@ fn do_mir_borrowck<'tcx>(
|
|||
for var_debug_info in &input_body.var_debug_info {
|
||||
if let VarDebugInfoContents::Place(place) = var_debug_info.value {
|
||||
if let Some(local) = place.as_local() {
|
||||
if let Some(prev_name) = local_names[local] && var_debug_info.name != prev_name {
|
||||
if let Some(prev_name) = local_names[local]
|
||||
&& var_debug_info.name != prev_name
|
||||
{
|
||||
span_bug!(
|
||||
var_debug_info.source_info.span,
|
||||
"local {:?} has many names (`{}` vs `{}`)",
|
||||
|
|
|
@ -49,7 +49,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
// If the query has created new universes and errors are going to be emitted, register the
|
||||
// cause of these new universes for improved diagnostics.
|
||||
let universe = self.infcx.universe();
|
||||
if old_universe != universe && let Some(error_info) = error_info {
|
||||
if old_universe != universe
|
||||
&& let Some(error_info) = error_info
|
||||
{
|
||||
let universe_info = error_info.to_universe_info(old_universe);
|
||||
for u in (old_universe + 1)..=universe {
|
||||
self.borrowck_context.constraints.universe_causes.insert(u, universe_info.clone());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue