Skip to content

Commit b35ef15

Browse files
committed
mutability ini
1 parent d8e3cfe commit b35ef15

File tree

3 files changed

+73
-18
lines changed

3 files changed

+73
-18
lines changed

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#![deny(rustc::untranslatable_diagnostic)]
2+
#![deny(rustc::diagnostic_outside_of_impl)]
3+
14
use rustc_errors::{
25
Applicability, Diagnostic, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed,
36
};
@@ -19,6 +22,7 @@ use rustc_span::symbol::{kw, Symbol};
1922
use rustc_span::{sym, BytePos, Span};
2023

2124
use crate::diagnostics::BorrowedContentSource;
25+
use crate::session_diagnostics::{FnMutBumpFn, ShowMutatingUpvar};
2226
use crate::MirBorrowckCtxt;
2327
use rustc_const_eval::util::collect_writes::FindAssignments;
2428

@@ -864,14 +868,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
864868
} else {
865869
bug!("not an upvar")
866870
};
867-
err.span_label(
868-
*span,
869-
format!(
870-
"calling `{}` requires mutable binding due to {}",
871-
self.describe_place(the_place_err).unwrap(),
872-
reason
873-
),
874-
);
871+
let place = self.describe_place(the_place_err).unwrap();
872+
let sub_label = ShowMutatingUpvar::RequireMutableBinding { place, reason, span: *span };
873+
err.subdiagnostic(sub_label);
875874
}
876875
}
877876

@@ -969,7 +968,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
969968

970969
/// Targeted error when encountering an `FnMut` closure where an `Fn` closure was expected.
971970
fn expected_fn_found_fn_mut_call(&self, err: &mut Diagnostic, sp: Span, act: &str) {
972-
err.span_label(sp, format!("cannot {act}"));
971+
err.subdiagnostic(FnMutBumpFn::Cannot { act, sp });
973972

974973
let hir = self.infcx.tcx.hir();
975974
let closure_id = self.mir_hir_id();
@@ -1022,9 +1021,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
10221021
_ => None,
10231022
};
10241023
if let Some(span) = arg {
1025-
err.span_label(span, "change this to accept `FnMut` instead of `Fn`");
1026-
err.span_label(func.span, "expects `Fn` instead of `FnMut`");
1027-
err.span_label(self.body.span, "in this closure");
1024+
err.subdiagnostic(FnMutBumpFn::AcceptFnMut { span });
1025+
err.subdiagnostic(FnMutBumpFn::AcceptFn { span: func.span });
1026+
err.subdiagnostic(FnMutBumpFn::Here { span: self.body.span });
10281027
look_at_return = false;
10291028
}
10301029
}
@@ -1045,12 +1044,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
10451044
kind: hir::ImplItemKind::Fn(sig, _),
10461045
..
10471046
}) => {
1048-
err.span_label(ident.span, "");
1049-
err.span_label(
1050-
sig.decl.output.span(),
1051-
"change this to return `FnMut` instead of `Fn`",
1052-
);
1053-
err.span_label(self.body.span, "in this closure");
1047+
err.subdiagnostic(FnMutBumpFn::EmptyLabel { span: ident.span });
1048+
err.subdiagnostic(FnMutBumpFn::ReturnFnMut { span: sig.decl.output.span() });
1049+
err.subdiagnostic(FnMutBumpFn::Here { span: self.body.span });
10541050
}
10551051
_ => {}
10561052
}

compiler/rustc_borrowck/src/session_diagnostics.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,17 @@ pub(crate) enum ClosureCannotAgain {
406406
},
407407
}
408408

409+
#[derive(SessionSubdiagnostic)]
410+
pub(crate) enum ShowMutatingUpvar {
411+
#[label(borrowck::require_mutable_binding)]
412+
RequireMutableBinding {
413+
place: String,
414+
reason: String,
415+
#[primary_span]
416+
span: Span,
417+
},
418+
}
419+
409420
#[derive(SessionSubdiagnostic)]
410421
pub(crate) enum CaptureCausedBy<'a> {
411422
#[label(borrowck::moved_by_call)]
@@ -484,3 +495,38 @@ pub(crate) enum NotImplCopy<'a, 'tcx> {
484495
#[note(borrowck::type_not_impl_Copy)]
485496
Note { place_desc: &'a str, ty: Ty<'tcx>, move_prefix: &'a str },
486497
}
498+
499+
#[derive(SessionSubdiagnostic)]
500+
pub(crate) enum FnMutBumpFn<'a> {
501+
#[label(borrowck::cannot_act)]
502+
Cannot {
503+
act: &'a str,
504+
#[primary_span]
505+
sp: Span,
506+
},
507+
#[label(borrowck::expects_fnmut_not_fn)]
508+
AcceptFnMut {
509+
#[primary_span]
510+
span: Span,
511+
},
512+
#[label(borrowck::expects_fn_not_fnmut)]
513+
AcceptFn {
514+
#[primary_span]
515+
span: Span,
516+
},
517+
#[label(borrowck::empty_label)]
518+
EmptyLabel {
519+
#[primary_span]
520+
span: Span,
521+
},
522+
#[label(borrowck::in_this_closure)]
523+
Here {
524+
#[primary_span]
525+
span: Span,
526+
},
527+
#[label(borrowck::return_fnmut)]
528+
ReturnFnMut {
529+
#[primary_span]
530+
span: Span,
531+
},
532+
}

compiler/rustc_error_messages/locales/en-US/borrowck.ftl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,16 @@ borrowck_type_not_impl_Copy =
203203
{$move_prefix}move occurs because {$place_desc} has type `{$ty}`, which does not implement the `Copy` trait
204204
borrowck_outlive_constraint_need_borrow_lasts =
205205
{$category}requires that `{$borrow_desc}` lasts for `{$region_name}`
206+
borrowck_require_mutable_binding =
207+
calling `{$place}` requires mutable binding due to {$reason}
208+
borrowck_cannot_act =
209+
cannot {$act}
210+
borrowck_expects_fnmut_not_fn =
211+
change this to accept `FnMut` instead of `Fn`
212+
borrowck_expects_fn_not_fnmut =
213+
expects `Fn` instead of `FnMut`
214+
borrowck_empty_label = {""}
215+
borrowck_in_this_closure =
216+
in this closure
217+
borrowck_return_fnmut =
218+
change this to return `FnMut` instead of `Fn`

0 commit comments

Comments
 (0)