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:
commit
46805805ab
11 changed files with 2108 additions and 2020 deletions
|
@ -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 {
|
||||
|
|
1985
src/librustc_mir/borrow_check/conflict_errors.rs
Normal file
1985
src/librustc_mir/borrow_check/conflict_errors.rs
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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
|
||||
|
|
9
src/test/ui/nll/dont-print-desugared-async.rs
Normal file
9
src/test/ui/nll/dont-print-desugared-async.rs
Normal 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() {}
|
12
src/test/ui/nll/dont-print-desugared-async.stderr
Normal file
12
src/test/ui/nll/dont-print-desugared-async.stderr
Normal 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`.
|
21
src/test/ui/nll/dont-print-desugared.rs
Normal file
21
src/test/ui/nll/dont-print-desugared.rs
Normal 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() {}
|
27
src/test/ui/nll/dont-print-desugared.stderr
Normal file
27
src/test/ui/nll/dont-print-desugared.stderr
Normal 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`.
|
Loading…
Reference in a new issue