summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs')
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs64
1 files changed, 44 insertions, 20 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index fe4a45b38..ee352e911 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1025,7 +1025,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
self.cannot_uniquely_borrow_by_two_closures(span, &desc_place, issued_span, None)
}
- (BorrowKind::Mut { .. }, BorrowKind::Shallow) => {
+ (BorrowKind::Mut { .. }, BorrowKind::Fake) => {
if let Some(immutable_section_description) =
self.classify_immutable_section(issued_borrow.assigned_place)
{
@@ -1117,11 +1117,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
)
}
- (BorrowKind::Shared, BorrowKind::Shared | BorrowKind::Shallow)
- | (
- BorrowKind::Shallow,
- BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Shallow,
- ) => unreachable!(),
+ (BorrowKind::Shared, BorrowKind::Shared | BorrowKind::Fake)
+ | (BorrowKind::Fake, BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Fake) => {
+ unreachable!()
+ }
};
if issued_spans == borrow_spans {
@@ -2130,21 +2129,27 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// misleading users in cases like `tests/ui/nll/borrowed-temporary-error.rs`.
/// We could expand the analysis to suggest hoising all of the relevant parts of
/// the users' code to make the code compile, but that could be too much.
- struct NestedStatementVisitor {
+ /// We found the `prop_expr` by the way to check whether the expression is a `FormatArguments`,
+ /// which is a special case since it's generated by the compiler.
+ struct NestedStatementVisitor<'tcx> {
span: Span,
current: usize,
found: usize,
+ prop_expr: Option<&'tcx hir::Expr<'tcx>>,
}
- impl<'tcx> Visitor<'tcx> for NestedStatementVisitor {
- fn visit_block(&mut self, block: &hir::Block<'tcx>) {
+ impl<'tcx> Visitor<'tcx> for NestedStatementVisitor<'tcx> {
+ fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {
self.current += 1;
walk_block(self, block);
self.current -= 1;
}
- fn visit_expr(&mut self, expr: &hir::Expr<'tcx>) {
+ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
if self.span == expr.span.source_callsite() {
self.found = self.current;
+ if self.prop_expr.is_none() {
+ self.prop_expr = Some(expr);
+ }
}
walk_expr(self, expr);
}
@@ -2162,22 +2167,40 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
span: proper_span,
current: 0,
found: 0,
+ prop_expr: None,
};
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 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)
&& let Some(p) = sm.span_to_margin(stmt.span)
&& let Ok(s) = sm.span_to_snippet(proper_span)
{
- let addition = format!("let binding = {};\n{}", s, " ".repeat(p));
- err.multipart_suggestion_verbose(
- msg,
- vec![
- (stmt.span.shrink_to_lo(), addition),
- (proper_span, "binding".to_string()),
- ],
- Applicability::MaybeIncorrect,
- );
+ if !is_format_arguments_item {
+ let addition = format!("let binding = {};\n{}", s, " ".repeat(p));
+ err.multipart_suggestion_verbose(
+ msg,
+ vec![
+ (stmt.span.shrink_to_lo(), addition),
+ (proper_span, "binding".to_string()),
+ ],
+ Applicability::MaybeIncorrect,
+ );
+ } else {
+ err.note("the result of `format_args!` can only be assigned directly if no placeholders in it's arguments are used");
+ err.note("to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>");
+ }
suggested = true;
break;
}
@@ -2620,7 +2643,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let loan_span = loan_spans.args_or_use();
let descr_place = self.describe_any_place(place.as_ref());
- if loan.kind == BorrowKind::Shallow {
+ if loan.kind == BorrowKind::Fake {
if let Some(section) = self.classify_immutable_section(loan.assigned_place) {
let mut err = self.cannot_mutate_in_immutable_section(
span,
@@ -2804,6 +2827,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Subslice { .. }
+ | ProjectionElem::Subtype(_)
| ProjectionElem::Index(_) => kind,
},
place_ty.projection_ty(tcx, elem),