Move rustc_mir::borrow_check to new crate rustc_borrowck.
This commit is contained in:
parent
8ceea01bb4
commit
31a61ccc38
64 changed files with 374 additions and 317 deletions
487
compiler/rustc_borrowck/src/borrowck_errors.rs
Normal file
487
compiler/rustc_borrowck/src/borrowck_errors.rs
Normal file
|
@ -0,0 +1,487 @@
|
|||
use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::{MultiSpan, Span};
|
||||
|
||||
impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
|
||||
crate fn cannot_move_when_borrowed(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> {
|
||||
struct_span_err!(self, span, E0505, "cannot move out of {} because it is borrowed", desc,)
|
||||
}
|
||||
|
||||
crate fn cannot_use_when_mutably_borrowed(
|
||||
&self,
|
||||
span: Span,
|
||||
desc: &str,
|
||||
borrow_span: Span,
|
||||
borrow_desc: &str,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
span,
|
||||
E0503,
|
||||
"cannot use {} because it was mutably borrowed",
|
||||
desc,
|
||||
);
|
||||
|
||||
err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_desc));
|
||||
err.span_label(span, format!("use of borrowed {}", borrow_desc));
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_act_on_uninitialized_variable(
|
||||
&self,
|
||||
span: Span,
|
||||
verb: &str,
|
||||
desc: &str,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
struct_span_err!(
|
||||
self,
|
||||
span,
|
||||
E0381,
|
||||
"{} of possibly-uninitialized variable: `{}`",
|
||||
verb,
|
||||
desc,
|
||||
)
|
||||
}
|
||||
|
||||
crate fn cannot_mutably_borrow_multiply(
|
||||
&self,
|
||||
new_loan_span: Span,
|
||||
desc: &str,
|
||||
opt_via: &str,
|
||||
old_loan_span: Span,
|
||||
old_opt_via: &str,
|
||||
old_load_end_span: Option<Span>,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let via =
|
||||
|msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) };
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
new_loan_span,
|
||||
E0499,
|
||||
"cannot borrow {}{} as mutable more than once at a time",
|
||||
desc,
|
||||
via(opt_via),
|
||||
);
|
||||
if old_loan_span == new_loan_span {
|
||||
// Both borrows are happening in the same place
|
||||
// Meaning the borrow is occurring in a loop
|
||||
err.span_label(
|
||||
new_loan_span,
|
||||
format!(
|
||||
"{}{} was mutably borrowed here in the previous iteration of the loop{}",
|
||||
desc,
|
||||
via(opt_via),
|
||||
opt_via,
|
||||
),
|
||||
);
|
||||
if let Some(old_load_end_span) = old_load_end_span {
|
||||
err.span_label(old_load_end_span, "mutable borrow ends here");
|
||||
}
|
||||
} else {
|
||||
err.span_label(
|
||||
old_loan_span,
|
||||
format!("first mutable borrow occurs here{}", via(old_opt_via)),
|
||||
);
|
||||
err.span_label(
|
||||
new_loan_span,
|
||||
format!("second mutable borrow occurs here{}", via(opt_via)),
|
||||
);
|
||||
if let Some(old_load_end_span) = old_load_end_span {
|
||||
err.span_label(old_load_end_span, "first borrow ends here");
|
||||
}
|
||||
}
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_uniquely_borrow_by_two_closures(
|
||||
&self,
|
||||
new_loan_span: Span,
|
||||
desc: &str,
|
||||
old_loan_span: Span,
|
||||
old_load_end_span: Option<Span>,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
new_loan_span,
|
||||
E0524,
|
||||
"two closures require unique access to {} at the same time",
|
||||
desc,
|
||||
);
|
||||
if old_loan_span == new_loan_span {
|
||||
err.span_label(
|
||||
old_loan_span,
|
||||
"closures are constructed here in different iterations of loop",
|
||||
);
|
||||
} else {
|
||||
err.span_label(old_loan_span, "first closure is constructed here");
|
||||
err.span_label(new_loan_span, "second closure is constructed here");
|
||||
}
|
||||
if let Some(old_load_end_span) = old_load_end_span {
|
||||
err.span_label(old_load_end_span, "borrow from first closure ends here");
|
||||
}
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_uniquely_borrow_by_one_closure(
|
||||
&self,
|
||||
new_loan_span: Span,
|
||||
container_name: &str,
|
||||
desc_new: &str,
|
||||
opt_via: &str,
|
||||
old_loan_span: Span,
|
||||
noun_old: &str,
|
||||
old_opt_via: &str,
|
||||
previous_end_span: Option<Span>,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
new_loan_span,
|
||||
E0500,
|
||||
"closure requires unique access to {} but {} is already borrowed{}",
|
||||
desc_new,
|
||||
noun_old,
|
||||
old_opt_via,
|
||||
);
|
||||
err.span_label(
|
||||
new_loan_span,
|
||||
format!("{} construction occurs here{}", container_name, opt_via),
|
||||
);
|
||||
err.span_label(old_loan_span, format!("borrow occurs here{}", old_opt_via));
|
||||
if let Some(previous_end_span) = previous_end_span {
|
||||
err.span_label(previous_end_span, "borrow ends here");
|
||||
}
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_reborrow_already_uniquely_borrowed(
|
||||
&self,
|
||||
new_loan_span: Span,
|
||||
container_name: &str,
|
||||
desc_new: &str,
|
||||
opt_via: &str,
|
||||
kind_new: &str,
|
||||
old_loan_span: Span,
|
||||
old_opt_via: &str,
|
||||
previous_end_span: Option<Span>,
|
||||
second_borrow_desc: &str,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
new_loan_span,
|
||||
E0501,
|
||||
"cannot borrow {}{} as {} because previous closure \
|
||||
requires unique access",
|
||||
desc_new,
|
||||
opt_via,
|
||||
kind_new,
|
||||
);
|
||||
err.span_label(
|
||||
new_loan_span,
|
||||
format!("{}borrow occurs here{}", second_borrow_desc, opt_via),
|
||||
);
|
||||
err.span_label(
|
||||
old_loan_span,
|
||||
format!("{} construction occurs here{}", container_name, old_opt_via),
|
||||
);
|
||||
if let Some(previous_end_span) = previous_end_span {
|
||||
err.span_label(previous_end_span, "borrow from closure ends here");
|
||||
}
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_reborrow_already_borrowed(
|
||||
&self,
|
||||
span: Span,
|
||||
desc_new: &str,
|
||||
msg_new: &str,
|
||||
kind_new: &str,
|
||||
old_span: Span,
|
||||
noun_old: &str,
|
||||
kind_old: &str,
|
||||
msg_old: &str,
|
||||
old_load_end_span: Option<Span>,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let via =
|
||||
|msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) };
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
span,
|
||||
E0502,
|
||||
"cannot borrow {}{} as {} because {} is also borrowed as {}{}",
|
||||
desc_new,
|
||||
via(msg_new),
|
||||
kind_new,
|
||||
noun_old,
|
||||
kind_old,
|
||||
via(msg_old),
|
||||
);
|
||||
|
||||
if msg_new == "" {
|
||||
// If `msg_new` is empty, then this isn't a borrow of a union field.
|
||||
err.span_label(span, format!("{} borrow occurs here", kind_new));
|
||||
err.span_label(old_span, format!("{} borrow occurs here", kind_old));
|
||||
} else {
|
||||
// If `msg_new` isn't empty, then this a borrow of a union field.
|
||||
err.span_label(
|
||||
span,
|
||||
format!(
|
||||
"{} borrow of {} -- which overlaps with {} -- occurs here",
|
||||
kind_new, msg_new, msg_old,
|
||||
),
|
||||
);
|
||||
err.span_label(old_span, format!("{} borrow occurs here{}", kind_old, via(msg_old)));
|
||||
}
|
||||
|
||||
if let Some(old_load_end_span) = old_load_end_span {
|
||||
err.span_label(old_load_end_span, format!("{} borrow ends here", kind_old));
|
||||
}
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_assign_to_borrowed(
|
||||
&self,
|
||||
span: Span,
|
||||
borrow_span: Span,
|
||||
desc: &str,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
span,
|
||||
E0506,
|
||||
"cannot assign to {} because it is borrowed",
|
||||
desc,
|
||||
);
|
||||
|
||||
err.span_label(borrow_span, format!("borrow of {} occurs here", desc));
|
||||
err.span_label(span, format!("assignment to borrowed {} occurs here", desc));
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_reassign_immutable(
|
||||
&self,
|
||||
span: Span,
|
||||
desc: &str,
|
||||
is_arg: bool,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" };
|
||||
struct_span_err!(self, span, E0384, "cannot assign {} {}", msg, desc)
|
||||
}
|
||||
|
||||
crate fn cannot_assign(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> {
|
||||
struct_span_err!(self, span, E0594, "cannot assign to {}", desc)
|
||||
}
|
||||
|
||||
crate fn cannot_move_out_of(
|
||||
&self,
|
||||
move_from_span: Span,
|
||||
move_from_desc: &str,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc,)
|
||||
}
|
||||
|
||||
/// Signal an error due to an attempt to move out of the interior
|
||||
/// of an array or slice. `is_index` is None when error origin
|
||||
/// didn't capture whether there was an indexing operation or not.
|
||||
crate fn cannot_move_out_of_interior_noncopy(
|
||||
&self,
|
||||
move_from_span: Span,
|
||||
ty: Ty<'_>,
|
||||
is_index: Option<bool>,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let type_name = match (&ty.kind(), is_index) {
|
||||
(&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
|
||||
(&ty::Slice(_), _) => "slice",
|
||||
_ => span_bug!(move_from_span, "this path should not cause illegal move"),
|
||||
};
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
move_from_span,
|
||||
E0508,
|
||||
"cannot move out of type `{}`, a non-copy {}",
|
||||
ty,
|
||||
type_name,
|
||||
);
|
||||
err.span_label(move_from_span, "cannot move out of here");
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_move_out_of_interior_of_drop(
|
||||
&self,
|
||||
move_from_span: Span,
|
||||
container_ty: Ty<'_>,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
move_from_span,
|
||||
E0509,
|
||||
"cannot move out of type `{}`, which implements the `Drop` trait",
|
||||
container_ty,
|
||||
);
|
||||
err.span_label(move_from_span, "cannot move out of here");
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_act_on_moved_value(
|
||||
&self,
|
||||
use_span: Span,
|
||||
verb: &str,
|
||||
optional_adverb_for_moved: &str,
|
||||
moved_path: Option<String>,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let moved_path = moved_path.map(|mp| format!(": `{}`", mp)).unwrap_or_default();
|
||||
|
||||
struct_span_err!(
|
||||
self,
|
||||
use_span,
|
||||
E0382,
|
||||
"{} of {}moved value{}",
|
||||
verb,
|
||||
optional_adverb_for_moved,
|
||||
moved_path,
|
||||
)
|
||||
}
|
||||
|
||||
crate fn cannot_borrow_path_as_mutable_because(
|
||||
&self,
|
||||
span: Span,
|
||||
path: &str,
|
||||
reason: &str,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,)
|
||||
}
|
||||
|
||||
crate fn cannot_mutate_in_immutable_section(
|
||||
&self,
|
||||
mutate_span: Span,
|
||||
immutable_span: Span,
|
||||
immutable_place: &str,
|
||||
immutable_section: &str,
|
||||
action: &str,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
mutate_span,
|
||||
E0510,
|
||||
"cannot {} {} in {}",
|
||||
action,
|
||||
immutable_place,
|
||||
immutable_section,
|
||||
);
|
||||
err.span_label(mutate_span, format!("cannot {}", action));
|
||||
err.span_label(immutable_span, format!("value is immutable in {}", immutable_section));
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_borrow_across_generator_yield(
|
||||
&self,
|
||||
span: Span,
|
||||
yield_span: Span,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
span,
|
||||
E0626,
|
||||
"borrow may still be in use when generator yields",
|
||||
);
|
||||
err.span_label(yield_span, "possible yield occurs here");
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> DiagnosticBuilder<'cx> {
|
||||
struct_span_err!(
|
||||
self,
|
||||
borrow_span,
|
||||
E0713,
|
||||
"borrow may still be in use when destructor runs",
|
||||
)
|
||||
}
|
||||
|
||||
crate fn path_does_not_live_long_enough(
|
||||
&self,
|
||||
span: Span,
|
||||
path: &str,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
struct_span_err!(self, span, E0597, "{} does not live long enough", path,)
|
||||
}
|
||||
|
||||
crate fn cannot_return_reference_to_local(
|
||||
&self,
|
||||
span: Span,
|
||||
return_kind: &str,
|
||||
reference_desc: &str,
|
||||
path_desc: &str,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
span,
|
||||
E0515,
|
||||
"cannot {RETURN} {REFERENCE} {LOCAL}",
|
||||
RETURN = return_kind,
|
||||
REFERENCE = reference_desc,
|
||||
LOCAL = path_desc,
|
||||
);
|
||||
|
||||
err.span_label(
|
||||
span,
|
||||
format!("{}s a {} data owned by the current function", return_kind, reference_desc),
|
||||
);
|
||||
|
||||
err
|
||||
}
|
||||
|
||||
crate fn cannot_capture_in_long_lived_closure(
|
||||
&self,
|
||||
closure_span: Span,
|
||||
closure_kind: &str,
|
||||
borrowed_path: &str,
|
||||
capture_span: Span,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
let mut err = struct_span_err!(
|
||||
self,
|
||||
closure_span,
|
||||
E0373,
|
||||
"{} may outlive the current function, \
|
||||
but it borrows {}, \
|
||||
which is owned by the current function",
|
||||
closure_kind,
|
||||
borrowed_path,
|
||||
);
|
||||
err.span_label(capture_span, format!("{} is borrowed here", borrowed_path))
|
||||
.span_label(closure_span, format!("may outlive borrowed value {}", borrowed_path));
|
||||
err
|
||||
}
|
||||
|
||||
crate fn thread_local_value_does_not_live_long_enough(
|
||||
&self,
|
||||
span: Span,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",)
|
||||
}
|
||||
|
||||
crate fn temporary_value_borrowed_for_too_long(&self, span: Span) -> DiagnosticBuilder<'cx> {
|
||||
struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",)
|
||||
}
|
||||
|
||||
fn struct_span_err_with_code<S: Into<MultiSpan>>(
|
||||
&self,
|
||||
sp: S,
|
||||
msg: &str,
|
||||
code: DiagnosticId,
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
self.infcx.tcx.sess.struct_span_err_with_code(sp, msg, code)
|
||||
}
|
||||
}
|
||||
|
||||
crate fn borrowed_data_escapes_closure<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
escape_span: Span,
|
||||
escapes_from: &str,
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
escape_span,
|
||||
E0521,
|
||||
"borrowed data escapes outside of {}",
|
||||
escapes_from,
|
||||
)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue