1
Fork 0

Dont show variables from desugarings in borrowck errors

This commit is contained in:
Matthew Jasper 2019-05-03 22:24:52 +01:00
parent 50a0defd5a
commit ebd6c7164e
9 changed files with 112 additions and 32 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. /// Creates a new `LocalDecl` for a temporary.
#[inline] #[inline]
pub fn new_temp(ty: Ty<'tcx>, span: Span) -> Self { pub fn new_temp(ty: Ty<'tcx>, span: Span) -> Self {

View file

@ -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 /// 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<(), ()> { fn append_local_to_string(&self, local_index: Local, buf: &mut String) -> Result<(), ()> {
let local = &self.mir.local_decls[local_index]; let local = &self.mir.local_decls[local_index];
match local.name { match local.name {
Some(name) => { Some(name) if !local.from_compiler_desugaring() => {
buf.push_str(&name.to_string()); buf.push_str(name.as_str().get());
Ok(()) Ok(())
} }
None => Err(()), _ => Err(()),
} }
} }

View file

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

View file

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

View file

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