Auto merge of #60984 - matthewjasper:borrowck-error-reporting-cleanup, r=pnkfelix

Borrowck error reporting cleanup

* Don't show variables created by desugarings in borrowck errors
* Move "conflict error" reporting to it's own module, so that `error_reporting` contains only common error reporting methods.
* Remove unused `ScopeTree` parameter.

r? @pnkfelix
This commit is contained in:
bors 2019-05-24 03:07:07 +00:00
commit 46805805ab
11 changed files with 2108 additions and 2020 deletions

View File

@ -915,6 +915,13 @@ impl<'tcx> LocalDecl<'tcx> {
}
}
/// Returns `true` is the local is from a compiler desugaring, e.g.,
/// `__next` from a `for` loop.
#[inline]
pub fn from_compiler_desugaring(&self) -> bool {
self.source_info.span.compiler_desugaring_kind().is_some()
}
/// Creates a new `LocalDecl` for a temporary.
#[inline]
pub fn new_temp(ty: Ty<'tcx>, span: Span) -> Self {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -54,6 +54,7 @@ crate mod borrow_set;
mod error_reporting;
mod flows;
mod location;
mod conflict_errors;
mod move_errors;
mod mutability_errors;
mod path_utils;

View File

@ -420,28 +420,31 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
);
}
if let Some(name) = local_decl.name {
err.span_label(
span,
format!(
"`{NAME}` is a `{SIGIL}` {DESC}, \
so the data it refers to cannot be {ACTED_ON}",
NAME = name,
SIGIL = pointer_sigil,
DESC = pointer_desc,
ACTED_ON = acted_on
),
);
} else {
err.span_label(
span,
format!(
"cannot {ACT} through `{SIGIL}` {DESC}",
ACT = act,
SIGIL = pointer_sigil,
DESC = pointer_desc
),
);
match local_decl.name {
Some(name) if !local_decl.from_compiler_desugaring() => {
err.span_label(
span,
format!(
"`{NAME}` is a `{SIGIL}` {DESC}, \
so the data it refers to cannot be {ACTED_ON}",
NAME = name,
SIGIL = pointer_sigil,
DESC = pointer_desc,
ACTED_ON = acted_on
),
);
}
_ => {
err.span_label(
span,
format!(
"cannot {ACT} through `{SIGIL}` {DESC}",
ACT = act,
SIGIL = pointer_sigil,
DESC = pointer_desc
),
);
}
}
}

View File

@ -112,7 +112,7 @@ impl BorrowExplanation {
};
match local_decl.name {
Some(local_name) => {
Some(local_name) if !local_decl.from_compiler_desugaring() => {
let message = format!(
"{B}borrow might be used here, when `{LOC}` is dropped \
and runs the {DTOR} for {TYPE}",
@ -130,7 +130,7 @@ impl BorrowExplanation {
);
}
}
None => {
_ => {
err.span_label(
local_decl.source_info.span,
format!(

View File

@ -8421,6 +8421,8 @@ impl<'a> Parser<'a> {
for (index, input) in decl.inputs.iter_mut().enumerate() {
let id = ast::DUMMY_NODE_ID;
let span = input.pat.span;
let desugared_span = self.sess.source_map()
.mark_span_with_reason(CompilerDesugaringKind::Async, span, None);
// Construct a name for our temporary argument.
let name = format!("__arg{}", index);
@ -8437,8 +8439,7 @@ impl<'a> Parser<'a> {
// this would affect the input to procedural macros, but they can have
// their span marked as being the result of a compiler desugaring so
// that they aren't linted against.
input.pat.span = self.sess.source_map().mark_span_with_reason(
CompilerDesugaringKind::Async, span, None);
input.pat.span = desugared_span;
(binding_mode, ident, true)
}
@ -8458,7 +8459,7 @@ impl<'a> Parser<'a> {
node: PatKind::Ident(
BindingMode::ByValue(Mutability::Immutable), ident, None,
),
span,
span: desugared_span,
}),
source: ArgSource::AsyncFn(input.pat.clone()),
})
@ -8471,7 +8472,7 @@ impl<'a> Parser<'a> {
pat: P(Pat {
id,
node: PatKind::Ident(binding_mode, ident, None),
span,
span: desugared_span,
}),
// We explicitly do not specify the type for this statement. When the user's
// argument type is `impl Trait` then this would require the

View File

@ -0,0 +1,9 @@
// Test that we don't show variables with from async fn desugaring
// edition:2018
#![feature(async_await)]
async fn async_fn(&ref mut s: &[i32]) {}
//~^ ERROR cannot borrow data in a `&` reference as mutable [E0596]
fn main() {}

View File

@ -0,0 +1,12 @@
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/dont-print-desugared-async.rs:6:20
|
LL | async fn async_fn(&ref mut s: &[i32]) {}
| -^^^^^^^^^
| ||
| |cannot borrow as mutable through `&` reference
| help: consider changing this to be a mutable reference: `&mut ref mut s`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0596`.

View File

@ -0,0 +1,21 @@
// Test that we don't show variables with from for loop desugaring
fn for_loop(s: &[i32]) {
for &ref mut x in s {}
//~^ ERROR cannot borrow data in a `&` reference as mutable [E0596]
}
struct D<'a>(&'a ());
impl Drop for D<'_> {
fn drop(&mut self) {}
}
fn for_loop_dropck(v: Vec<D<'static>>) {
for ref mut d in v {
let y = ();
*d = D(&y); //~ ERROR `y` does not live long enough
}
}
fn main() {}

View File

@ -0,0 +1,27 @@
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/dont-print-desugared.rs:4:10
|
LL | for &ref mut x in s {}
| -^^^^^^^^^
| ||
| |cannot borrow as mutable through `&` reference
| help: consider changing this to be a mutable reference: `&mut ref mut x`
error[E0597]: `y` does not live long enough
--> $DIR/dont-print-desugared.rs:17:16
|
LL | for ref mut d in v {
| - a temporary with access to the borrow is created here ...
LL | let y = ();
LL | *d = D(&y);
| ^^ borrowed value does not live long enough
LL | }
| -
| |
| `y` dropped here while still borrowed
| ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0596, E0597.
For more information about an error, try `rustc --explain E0596`.