Dont show variables from desugarings in borrowck errors
This commit is contained in:
parent
50a0defd5a
commit
ebd6c7164e
9 changed files with 112 additions and 32 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 {
|
||||
|
|
|
@ -1760,15 +1760,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
/// Appends end-user visible description of the `local` place to `buf`. If `local` doesn't have
|
||||
/// a name, then `Err` is returned
|
||||
/// a name, or its name was generated by the compiler, then `Err` is returned
|
||||
fn append_local_to_string(&self, local_index: Local, buf: &mut String) -> Result<(), ()> {
|
||||
let local = &self.mir.local_decls[local_index];
|
||||
match local.name {
|
||||
Some(name) => {
|
||||
buf.push_str(&name.to_string());
|
||||
Some(name) if !local.from_compiler_desugaring() => {
|
||||
buf.push_str(name.as_str().get());
|
||||
Ok(())
|
||||
}
|
||||
None => Err(()),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -420,7 +420,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
if let Some(name) = local_decl.name {
|
||||
match local_decl.name {
|
||||
Some(name) if !local_decl.from_compiler_desugaring() => {
|
||||
err.span_label(
|
||||
span,
|
||||
format!(
|
||||
|
@ -432,7 +433,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
ACTED_ON = acted_on
|
||||
),
|
||||
);
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
err.span_label(
|
||||
span,
|
||||
format!(
|
||||
|
@ -444,6 +446,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Place::Projection(box Projection {
|
||||
base,
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -8423,6 +8423,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);
|
||||
|
@ -8439,8 +8441,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)
|
||||
}
|
||||
|
@ -8460,7 +8461,7 @@ impl<'a> Parser<'a> {
|
|||
node: PatKind::Ident(
|
||||
BindingMode::ByValue(Mutability::Immutable), ident, None,
|
||||
),
|
||||
span,
|
||||
span: desugared_span,
|
||||
}),
|
||||
source: ArgSource::AsyncFn(input.pat.clone()),
|
||||
})
|
||||
|
@ -8473,7 +8474,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…
Add table
Add a link
Reference in a new issue