summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_borrowck/src/diagnostics/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_borrowck/src/diagnostics/mod.rs')
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs123
1 files changed, 86 insertions, 37 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 534d9ecae..4e2271a30 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -70,7 +70,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location: Location,
place: PlaceRef<'tcx>,
diag: &mut Diagnostic,
- ) {
+ ) -> bool {
debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place);
let mut target = place.local_or_deref_local();
for stmt in &self.body[location.block].statements[location.statement_index..] {
@@ -78,7 +78,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let StatementKind::Assign(box (into, Rvalue::Use(from))) = &stmt.kind {
debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from);
match from {
- Operand::Copy(ref place) | Operand::Move(ref place)
+ Operand::Copy(place) | Operand::Move(place)
if target == place.local_or_deref_local() =>
{
target = into.local_or_deref_local()
@@ -101,12 +101,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
debug!("add_moved_or_invoked_closure_note: id={:?}", id);
if Some(self.infcx.tcx.parent(id)) == self.infcx.tcx.lang_items().fn_once_trait() {
let closure = match args.first() {
- Some(Operand::Copy(ref place)) | Some(Operand::Move(ref place))
+ Some(Operand::Copy(place) | Operand::Move(place))
if target == place.local_or_deref_local() =>
{
place.local_or_deref_local().unwrap()
}
- _ => return,
+ _ => return false,
};
debug!("add_moved_or_invoked_closure_note: closure={:?}", closure);
@@ -125,7 +125,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
),
);
- return;
+ return true;
}
}
}
@@ -149,9 +149,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
),
);
+ return true;
}
}
}
+ false
}
/// End-user visible description of `place` if one can be found.
@@ -350,7 +352,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} else {
def.non_enum_variant()
};
- if !including_tuple_field.0 && variant.ctor_kind == CtorKind::Fn {
+ if !including_tuple_field.0 && variant.ctor_kind() == Some(CtorKind::Fn) {
return None;
}
Some(variant.fields[field.index()].name.to_string())
@@ -437,9 +439,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if !is_terminator {
continue;
} else if let Some(Terminator {
- kind: TerminatorKind::Call { ref func, from_hir_call: false, .. },
+ kind: TerminatorKind::Call { func, from_hir_call: false, .. },
..
- }) = bbd.terminator
+ }) = &bbd.terminator
{
if let Some(source) =
BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx)
@@ -588,22 +590,45 @@ impl UseSpans<'_> {
}
}
- // Add a span label to the arguments of the closure, if it exists.
+ /// Add a span label to the arguments of the closure, if it exists.
pub(super) fn args_span_label(self, err: &mut Diagnostic, message: impl Into<String>) {
if let UseSpans::ClosureUse { args_span, .. } = self {
err.span_label(args_span, message);
}
}
- // Add a span label to the use of the captured variable, if it exists.
- // only adds label to the `path_span`
- pub(super) fn var_span_label_path_only(self, err: &mut Diagnostic, message: impl Into<String>) {
- if let UseSpans::ClosureUse { path_span, .. } = self {
- err.span_label(path_span, message);
+ /// Add a span label to the use of the captured variable, if it exists.
+ /// only adds label to the `path_span`
+ pub(super) fn var_path_only_subdiag(
+ self,
+ err: &mut Diagnostic,
+ action: crate::InitializationRequiringAction,
+ ) {
+ use crate::session_diagnostics::CaptureVarPathUseCause::*;
+ use crate::InitializationRequiringAction::*;
+ if let UseSpans::ClosureUse { generator_kind, path_span, .. } = self {
+ match generator_kind {
+ Some(_) => {
+ err.subdiagnostic(match action {
+ Borrow => BorrowInGenerator { path_span },
+ MatchOn | Use => UseInGenerator { path_span },
+ Assignment => AssignInGenerator { path_span },
+ PartialAssignment => AssignPartInGenerator { path_span },
+ });
+ }
+ None => {
+ err.subdiagnostic(match action {
+ Borrow => BorrowInClosure { path_span },
+ MatchOn | Use => UseInClosure { path_span },
+ Assignment => AssignInClosure { path_span },
+ PartialAssignment => AssignPartInClosure { path_span },
+ });
+ }
+ }
}
}
- // Add a span label to the use of the captured variable, if it exists.
+ /// Add a span label to the use of the captured variable, if it exists.
pub(super) fn var_span_label(
self,
err: &mut Diagnostic,
@@ -623,6 +648,35 @@ impl UseSpans<'_> {
}
}
+ /// Add a subdiagnostic to the use of the captured variable, if it exists.
+ pub(super) fn var_subdiag(
+ self,
+ err: &mut Diagnostic,
+ kind: Option<rustc_middle::mir::BorrowKind>,
+ f: impl Fn(Option<GeneratorKind>, Span) -> crate::session_diagnostics::CaptureVarCause,
+ ) {
+ use crate::session_diagnostics::CaptureVarKind::*;
+ if let UseSpans::ClosureUse { generator_kind, capture_kind_span, path_span, .. } = self {
+ if capture_kind_span != path_span {
+ err.subdiagnostic(match kind {
+ Some(kd) => match kd {
+ rustc_middle::mir::BorrowKind::Shared
+ | rustc_middle::mir::BorrowKind::Shallow
+ | rustc_middle::mir::BorrowKind::Unique => {
+ Immute { kind_span: capture_kind_span }
+ }
+
+ rustc_middle::mir::BorrowKind::Mut { .. } => {
+ Mut { kind_span: capture_kind_span }
+ }
+ },
+ None => Move { kind_span: capture_kind_span },
+ });
+ };
+ err.subdiagnostic(f(generator_kind, path_span));
+ }
+ }
+
/// Returns `false` if this place is not used in a closure.
pub(super) fn for_closure(&self) -> bool {
match *self {
@@ -757,33 +811,30 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
};
debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
- if let StatementKind::Assign(box (_, Rvalue::Aggregate(ref kind, ref places))) = stmt.kind {
- match **kind {
- AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) => {
- debug!("move_spans: def_id={:?} places={:?}", def_id, places);
- 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,
- };
- }
- }
- _ => {}
+ if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind
+ && let AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) = **kind
+ {
+ debug!("move_spans: def_id={:?} places={:?}", def_id, places);
+ 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,
+ };
}
}
// StatementKind::FakeRead only contains a def_id if they are introduced as a result
// of pattern matching within a closure.
- if let StatementKind::FakeRead(box (cause, ref place)) = stmt.kind {
+ if let StatementKind::FakeRead(box (cause, place)) = stmt.kind {
match cause {
FakeReadCause::ForMatchedPlace(Some(closure_def_id))
| FakeReadCause::ForLet(Some(closure_def_id)) => {
debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place);
- let places = &[Operand::Move(*place)];
+ let places = &[Operand::Move(place)];
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
self.closure_span(closure_def_id, moved_place, places)
{
@@ -870,7 +921,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
debug!("borrow_spans: use_span={:?} location={:?}", use_span, location);
let target = match self.body[location.block].statements.get(location.statement_index) {
- Some(&Statement { kind: StatementKind::Assign(box (ref place, _)), .. }) => {
+ Some(Statement { kind: StatementKind::Assign(box (place, _)), .. }) => {
if let Some(local) = place.as_local() {
local
} else {
@@ -886,9 +937,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
- if let StatementKind::Assign(box (_, Rvalue::Aggregate(ref kind, ref places))) =
- stmt.kind
- {
+ if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind {
let (&def_id, is_generator) = match kind {
box AggregateKind::Closure(def_id, _) => (def_id, false),
box AggregateKind::Generator(def_id, _, _) => (def_id, true),